Ticket #8661: diff.2

File diff.2, 44.0 KB (added by SF/robinwatts, 13 years ago)

Revised patch

Line 
1Index: sound/module.mk
2===================================================================
3--- sound/module.mk (revision 26884)
4+++ sound/module.mk (working copy)
5@@ -16,7 +16,6 @@
6 mp3.o \
7 mpu401.o \
8 null.o \
9- rate.o \
10 voc.o \
11 vorbis.o \
12 wave.o \
13@@ -31,5 +30,14 @@
14 softsynth/fluidsynth.o \
15 softsynth/mt32.o \
16
17+ifndef ARM
18+MODULE_OBJS += \
19+ rate.o
20+else
21+MODULE_OBJS += \
22+ rate_arm.o \
23+ rate_arm_asm.o
24+endif
25+
26 # Include common rules
27 include $(srcdir)/rules.mk
28Index: sound/rate_arm.cpp
29===================================================================
30--- sound/rate_arm.cpp (revision 0)
31+++ sound/rate_arm.cpp (revision 0)
32@@ -0,0 +1,416 @@
33+/* ScummVM - Scumm Interpreter
34+ * Copyright (C) 2001-2006 The ScummVM project
35+ *
36+ * This program is free software; you can redistribute it and/or
37+ * modify it under the terms of the GNU General Public License
38+ * as published by the Free Software Foundation; either version 2
39+ * of the License, or (at your option) any later version.
40+
41+ * This program is distributed in the hope that it will be useful,
42+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
43+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
44+ * GNU General Public License for more details.
45+
46+ * You should have received a copy of the GNU General Public License
47+ * along with this program; if not, write to the Free Software
48+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
49+ *
50+ * $URL$
51+ * $Id$
52+ *
53+ */
54+
55+/*
56+ * The code in this file, together with the rate_arm_asm.s file offers
57+ * an ARM optimised version of the code in rate.cpp. The operation of this
58+ * code should be identical to that of rate.cpp, but faster. The heavy
59+ * lifting is done in the assembler file.
60+ *
61+ * To be as portable as possible we implement the core routines with C
62+ * linkage in assembly, and implement the C++ routines that call into
63+ * the C here. The C++ symbol mangling varies wildly between compilers,
64+ * so this is the simplest way to ensure that the C/C++ combination should
65+ * work on as many ARM based platforms as possible.
66+ *
67+ * Essentially the algorithm herein is the same as that in rate.cpp, so
68+ * anyone seeking to understand this should attempt to understand that
69+ * first. That code was based in turn on code with Copyright 1998 Fabrice
70+ * Bellard - part of SoX (http://sox.sourceforge.net).
71+ * Max Horn adapted that code to the needs of ScummVM and partially rewrote
72+ * it, in the process removing any use of floating point arithmetic. Various
73+ * other improvments over the original code were made.
74+ */
75+
76+#include "common/stdafx.h"
77+#include "sound/audiostream.h"
78+#include "sound/rate.h"
79+#include "sound/mixer.h"
80+#include "common/util.h"
81+
82+namespace Audio {
83+
84+/**
85+ * The precision of the fractional computations used by the rate converter.
86+ * Normally you should never have to modify this value.
87+ */
88+#define FRAC_BITS 16
89+
90+/**
91+ * The size of the intermediate input cache. Bigger values may increase
92+ * performance, but only until some point (depends largely on cache size,
93+ * target processor and various other factors), at which it will decrease
94+ * again.
95+ */
96+#define INTERMEDIATE_BUFFER_SIZE 512
97+
98+
99+/**
100+ * Audio rate converter based on simple resampling. Used when no
101+ * interpolation is required.
102+ *
103+ * Limited to sampling frequency <= 65535 Hz.
104+ */
105+typedef struct {
106+ const st_sample_t *inPtr;
107+ int inLen;
108+
109+ /** position of how far output is ahead of input */
110+ /** Holds what would have been opos-ipos */
111+ long opos;
112+
113+ /** fractional position increment in the output stream */
114+ long opos_inc;
115+
116+ st_sample_t inBuf[INTERMEDIATE_BUFFER_SIZE];
117+} SimpleRateDetails;
118+
119+template<bool stereo, bool reverseStereo>
120+class SimpleRateConverter : public RateConverter {
121+protected:
122+ SimpleRateDetails sr;
123+public:
124+ SimpleRateConverter(st_rate_t inrate, st_rate_t outrate);
125+ int flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r);
126+ int drain(st_sample_t *obuf, st_size_t osamp, st_volume_t vol) {
127+ return (ST_SUCCESS);
128+ }
129+};
130+
131+
132+/*
133+ * Prepare processing.
134+ */
135+template<bool stereo, bool reverseStereo>
136+SimpleRateConverter<stereo, reverseStereo>::SimpleRateConverter(st_rate_t inrate, st_rate_t outrate) {
137+ if (inrate == outrate) {
138+ error("Input and Output rates must be different to use rate effect");
139+ }
140+
141+ if ((inrate % outrate) != 0) {
142+ error("Input rate must be a multiple of Output rate to use rate effect");
143+ }
144+
145+ if (inrate >= 65536 || outrate >= 65536) {
146+ error("rate effect can only handle rates < 65536");
147+ }
148+
149+ sr.opos = 1;
150+
151+ /* increment */
152+ sr.opos_inc = inrate / outrate;
153+
154+ sr.inLen = 0;
155+}
156+
157+extern "C" void ARM_SimpleRate_M(AudioStream &input,
158+ int (*fn)(Audio::AudioStream&,int16*,int),
159+ SimpleRateDetails *sr,
160+ st_sample_t *obuf,
161+ st_size_t osamp,
162+ st_volume_t vol_l,
163+ st_volume_t vol_r);
164+
165+extern "C" void ARM_SimpleRate_S(AudioStream &input,
166+ int (*fn)(Audio::AudioStream&,int16*,int),
167+ SimpleRateDetails *sr,
168+ st_sample_t *obuf,
169+ st_size_t osamp,
170+ st_volume_t vol_l,
171+ st_volume_t vol_r);
172+
173+extern "C" void ARM_SimpleRate_R(AudioStream &input,
174+ int (*fn)(Audio::AudioStream&,int16*,int),
175+ SimpleRateDetails *sr,
176+ st_sample_t *obuf,
177+ st_size_t osamp,
178+ st_volume_t vol_l,
179+ st_volume_t vol_r);
180+
181+extern "C" int SimpleRate_readFudge(Audio::AudioStream &input,
182+ int16 *a, int b)
183+{
184+ return input.readBuffer(a, b);
185+}
186+
187+template<bool stereo, bool reverseStereo>
188+int SimpleRateConverter<stereo, reverseStereo>::flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) {
189+
190+ if (!stereo) {
191+ ARM_SimpleRate_M(input,
192+ &SimpleRate_readFudge,
193+ &sr,
194+ obuf, osamp, vol_l, vol_r);
195+ } else if (reverseStereo) {
196+ ARM_SimpleRate_R(input,
197+ &SimpleRate_readFudge,
198+ &sr,
199+ obuf, osamp, vol_l, vol_r);
200+ } else {
201+ ARM_SimpleRate_S(input,
202+ &SimpleRate_readFudge,
203+ &sr,
204+ obuf, osamp, vol_l, vol_r);
205+ }
206+ return (ST_SUCCESS);
207+}
208+
209+/**
210+ * Audio rate converter based on simple linear Interpolation.
211+ *
212+ * The use of fractional increment allows us to use no buffer. It
213+ * avoid the problems at the end of the buffer we had with the old
214+ * method which stored a possibly big buffer of size
215+ * lcm(in_rate,out_rate).
216+ *
217+ * Limited to sampling frequency <= 65535 Hz.
218+ */
219+
220+typedef struct {
221+ const st_sample_t *inPtr;
222+ int inLen;
223+
224+ /** position of how far output is ahead of input */
225+ /** Holds what would have been opos-ipos */
226+ long opos;
227+
228+ /** integer position increment in the output stream */
229+ long opos_inc;
230+
231+ /** current sample(s) in the input stream (left/right channel) */
232+ st_sample_t icur[2];
233+ /** last sample(s) in the input stream (left/right channel) */
234+ st_sample_t ilast[2];
235+
236+ /** fractional position in the output stream */
237+ long opos_frac;
238+
239+ /** fractional position increment in the output stream */
240+ long opos_inc_frac;
241+
242+ st_sample_t inBuf[INTERMEDIATE_BUFFER_SIZE];
243+} LinearRateDetails;
244+
245+extern "C" void ARM_LinearRate_M(AudioStream &input,
246+ int (*fn)(Audio::AudioStream&,int16*,int),
247+ LinearRateDetails *lr,
248+ st_sample_t *obuf,
249+ st_size_t osamp,
250+ st_volume_t vol_l,
251+ st_volume_t vol_r);
252+
253+extern "C" void ARM_LinearRate_S(AudioStream &input,
254+ int (*fn)(Audio::AudioStream&,int16*,int),
255+ LinearRateDetails *lr,
256+ st_sample_t *obuf,
257+ st_size_t osamp,
258+ st_volume_t vol_l,
259+ st_volume_t vol_r);
260+
261+extern "C" void ARM_LinearRate_R(AudioStream &input,
262+ int (*fn)(Audio::AudioStream&,int16*,int),
263+ LinearRateDetails *lr,
264+ st_sample_t *obuf,
265+ st_size_t osamp,
266+ st_volume_t vol_l,
267+ st_volume_t vol_r);
268+
269+template<bool stereo, bool reverseStereo>
270+class LinearRateConverter : public RateConverter {
271+protected:
272+ LinearRateDetails lr;
273+
274+public:
275+ LinearRateConverter(st_rate_t inrate, st_rate_t outrate);
276+ int flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r);
277+ int drain(st_sample_t *obuf, st_size_t osamp, st_volume_t vol) {
278+ return (ST_SUCCESS);
279+ }
280+};
281+
282+
283+/*
284+ * Prepare processing.
285+ */
286+template<bool stereo, bool reverseStereo>
287+LinearRateConverter<stereo, reverseStereo>::LinearRateConverter(st_rate_t inrate, st_rate_t outrate) {
288+ unsigned long incr;
289+
290+ if (inrate == outrate) {
291+ error("Input and Output rates must be different to use rate effect");
292+ }
293+
294+ if (inrate >= 65536 || outrate >= 65536) {
295+ error("rate effect can only handle rates < 65536");
296+ }
297+
298+ lr.opos_frac = 0;
299+ lr.opos = 1;
300+
301+ /* increment */
302+ incr = (inrate << FRAC_BITS) / outrate;
303+
304+ lr.opos_inc_frac = incr & ((1UL << FRAC_BITS) - 1);
305+ lr.opos_inc = incr >> FRAC_BITS;
306+
307+ lr.ilast[0] = lr.ilast[1] = 0;
308+ lr.icur[0] = lr.icur[1] = 0;
309+
310+ lr.inLen = 0;
311+}
312+
313+/*
314+ * Processed signed long samples from ibuf to obuf.
315+ * Return number of samples processed.
316+ */
317+template<bool stereo, bool reverseStereo>
318+int LinearRateConverter<stereo, reverseStereo>::flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) {
319+
320+ if (!stereo) {
321+ ARM_LinearRate_M(input,
322+ &SimpleRate_readFudge,
323+ &lr,
324+ obuf, osamp, vol_l, vol_r);
325+ } else if (reverseStereo) {
326+ ARM_LinearRate_R(input,
327+ &SimpleRate_readFudge,
328+ &lr,
329+ obuf, osamp, vol_l, vol_r);
330+ } else {
331+ ARM_LinearRate_S(input,
332+ &SimpleRate_readFudge,
333+ &lr,
334+ obuf, osamp, vol_l, vol_r);
335+ }
336+ return (ST_SUCCESS);
337+}
338+
339+
340+#pragma mark -
341+
342+
343+/**
344+ * Simple audio rate converter for the case that the inrate equals the outrate.
345+ */
346+extern "C" void ARM_CopyRate_M(st_size_t len,
347+ st_sample_t *obuf,
348+ st_volume_t vol_l,
349+ st_volume_t vol_r,
350+ st_sample_t *_buffer);
351+
352+extern "C" void ARM_CopyRate_S(st_size_t len,
353+ st_sample_t *obuf,
354+ st_volume_t vol_l,
355+ st_volume_t vol_r,
356+ st_sample_t *_buffer);
357+
358+extern "C" void ARM_CopyRate_R(st_size_t len,
359+ st_sample_t *obuf,
360+ st_volume_t vol_l,
361+ st_volume_t vol_r,
362+ st_sample_t *_buffer);
363+
364+
365+template<bool stereo, bool reverseStereo>
366+class CopyRateConverter : public RateConverter {
367+ st_sample_t *_buffer;
368+ st_size_t _bufferSize;
369+public:
370+ CopyRateConverter() : _buffer(0), _bufferSize(0) {}
371+ ~CopyRateConverter() {
372+ free(_buffer);
373+ }
374+
375+ virtual int flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) {
376+ assert(input.isStereo() == stereo);
377+
378+ st_sample_t *ptr;
379+ st_size_t len;
380+
381+ if (stereo)
382+ osamp *= 2;
383+
384+ // Reallocate temp buffer, if necessary
385+ if (osamp > _bufferSize) {
386+ free(_buffer);
387+ _buffer = (st_sample_t *)malloc(osamp * 2);
388+ _bufferSize = osamp;
389+ }
390+
391+ // Read up to 'osamp' samples into our temporary buffer
392+ len = input.readBuffer(_buffer, osamp);
393+ if (len <= 0)
394+ return (ST_SUCCESS);
395+
396+ // Mix the data into the output buffer
397+ if (stereo && reverseStereo)
398+ ARM_CopyRate_R(len, obuf, vol_l, vol_r, _buffer);
399+ else if (stereo)
400+ ARM_CopyRate_S(len, obuf, vol_l, vol_r, _buffer);
401+ else
402+ ARM_CopyRate_M(len, obuf, vol_l, vol_r, _buffer);
403+
404+ return (ST_SUCCESS);
405+ }
406+ virtual int drain(st_sample_t *obuf, st_size_t osamp, st_volume_t vol) {
407+ return (ST_SUCCESS);
408+ }
409+};
410+
411+
412+#pragma mark -
413+
414+
415+/**
416+ * Create and return a RateConverter object for the specified input and output rates.
417+ */
418+RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate, bool stereo, bool reverseStereo) {
419+ if (inrate != outrate) {
420+ if ((inrate % outrate) == 0) {
421+ if (stereo) {
422+ if (reverseStereo)
423+ return new SimpleRateConverter<true, true>(inrate, outrate);
424+ else
425+ return new SimpleRateConverter<true, false>(inrate, outrate);
426+ } else
427+ return new SimpleRateConverter<false, false>(inrate, outrate);
428+ } else {
429+ if (stereo) {
430+ if (reverseStereo)
431+ return new LinearRateConverter<true, true>(inrate, outrate);
432+ else
433+ return new LinearRateConverter<true, false>(inrate, outrate);
434+ } else
435+ return new LinearRateConverter<false, false>(inrate, outrate);
436+ }
437+ } else {
438+ if (stereo) {
439+ if (reverseStereo)
440+ return new CopyRateConverter<true, true>();
441+ else
442+ return new CopyRateConverter<true, false>();
443+ } else
444+ return new CopyRateConverter<false, false>();
445+ }
446+}
447+
448+} // End of namespace Audio
449
450Property changes on: sound/rate_arm.cpp
451___________________________________________________________________
452Name: svn:executable
453 + *
454
455Index: sound/rate_arm_asm.s
456===================================================================
457--- sound/rate_arm_asm.s (revision 0)
458+++ sound/rate_arm_asm.s (revision 0)
459@@ -0,0 +1,689 @@
460+@ ScummVM Scumm Interpreter
461+@ Copyright (C) 2007 The ScummVM project
462+@
463+@ This program is free software@ you can redistribute it and/or
464+@ modify it under the terms of the GNU General Public License
465+@ as published by the Free Software Foundation@ either version 2
466+@ of the License, or (at your option) any later version.
467+@
468+@ This program is distributed in the hope that it will be useful,
469+@ but WITHOUT ANY WARRANTY@ without even the implied warranty of
470+@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
471+@ GNU General Public License for more details.
472+@
473+@ You should have received a copy of the GNU General Public License
474+@ along with this program@ if not, write to the Free Software
475+@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
476+@
477+@ $URL: $
478+@ $Id: $
479+@
480+@ @author Robin Watts (robin@wss.co.uk)
481+@
482+@ This file, together with rate_arm.cpp, provides an ARM optimised version
483+@ of rate.cpp. The algorithm is essentially the same as that within rate.cpp
484+@ so to understand this file you should understand rate.cpp first.
485+
486+ .text
487+
488+ .global ARM_CopyRate_M
489+ .global ARM_CopyRate_S
490+ .global ARM_CopyRate_R
491+ .global ARM_SimpleRate_M
492+ .global ARM_SimpleRate_S
493+ .global ARM_SimpleRate_R
494+ .global ARM_LinearRate_M
495+ .global ARM_LinearRate_S
496+ .global ARM_LinearRate_R
497+
498+ARM_CopyRate_M:
499+ @ r0 = len
500+ @ r1 = obuf
501+ @ r2 = vol_l
502+ @ r3 = vol_r
503+ @ <> = ptr
504+ LDR r12,[r13]
505+ STMFD r13!,{r4-r7,r14}
506+
507+ MOV r14,#0 @ r14= 0
508+ ORR r2, r2, r2, LSL #8 @ r2 = vol_l as 16 bits
509+ ORR r3, r3, r3, LSL #8 @ r3 = vol_r as 16 bits
510+CopyRate_M_loop:
511+ LDRSH r5, [r12], #2 @ r5 = tmp0 = tmp1 = *ptr++
512+ LDRSH r6, [r1] @ r6 = obuf[0]
513+ LDRSH r7, [r1, #2] @ r7 = obuf[1]
514+ MUL r4, r2, r5 @ r4 = tmp0*vol_l
515+ MUL r5, r3, r5 @ r5 = tmp1*vol_r
516+
517+ ADDS r6, r4, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp0*vol_l
518+ RSCVS r6, r14,#1<<31 @ Clamp r6
519+ ADDS r7, r5, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp1*vol_r
520+ RSCVS r7, r14,#1<<31 @ Clamp r7
521+
522+ MOV r6, r6, LSR #16 @ Shift back to halfword
523+ MOV r7, r7, LSR #16 @ Shift back to halfword
524+
525+ STRH r6, [r1], #2 @ Store output value
526+ STRH r7, [r1], #2 @ Store output value
527+
528+ SUBS r0,r0,#1 @ len--
529+ BGT CopyRate_M_loop @ and loop
530+
531+ LDMFD r13!,{r4-r7,PC}
532+
533+ARM_CopyRate_S:
534+ @ r0 = len
535+ @ r1 = obuf
536+ @ r2 = vol_l
537+ @ r3 = vol_r
538+ @ <> = ptr
539+ LDR r12,[r13]
540+ STMFD r13!,{r4-r7,r14}
541+
542+ MOV r14,#0 @ r14= 0
543+ ORR r2, r2, r2, LSL #8 @ r2 = vol_l as 16 bits
544+ ORR r3, r3, r3, LSL #8 @ r3 = vol_r as 16 bits
545+CopyRate_S_loop:
546+ LDRSH r4, [r12],#2 @ r4 = tmp0 = *ptr++
547+ LDRSH r5, [r12],#2 @ r5 = tmp1 = *ptr++
548+ LDRSH r6, [r1] @ r6 = obuf[0]
549+ LDRSH r7, [r1,#2] @ r7 = obuf[1]
550+ MUL r4, r2, r4 @ r5 = tmp0*vol_l
551+ MUL r5, r3, r5 @ r6 = tmp1*vol_r
552+
553+ ADDS r6, r4, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp0*vol_l
554+ RSCVS r6, r14,#1<<31 @ Clamp r6
555+ ADDS r7, r5, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp1*vol_r
556+ RSCVS r7, r14,#1<<31 @ Clamp r7
557+
558+ MOV r6, r6, LSR #16 @ Shift back to halfword
559+ MOV r7, r7, LSR #16 @ Shift back to halfword
560+
561+ STRH r6, [r1],#2 @ Store output value
562+ STRH r7, [r1],#2 @ Store output value
563+
564+ SUBS r0,r0,#2 @ len -= 2
565+ BGT CopyRate_S_loop @ and loop
566+
567+ LDMFD r13!,{r4-r7,PC}
568+
569+ARM_CopyRate_R:
570+ @ r0 = len
571+ @ r1 = obuf
572+ @ r2 = vol_l
573+ @ r3 = vol_r
574+ @ <> = ptr
575+ LDR r12,[r13]
576+ STMFD r13!,{r4-r7,r14}
577+
578+ MOV r14,#0 @ r14= 0
579+ ORR r2, r2, r2, LSL #8 @ r2 = vol_l as 16 bits
580+ ORR r3, r3, r3, LSL #8 @ r3 = vol_r as 16 bits
581+CopyRate_R_loop:
582+ LDRSH r5, [r12],#2 @ r5 = tmp1 = *ptr++
583+ LDRSH r4, [r12],#2 @ r4 = tmp0 = *ptr++
584+ LDRSH r6, [r1] @ r6 = obuf[0]
585+ LDRSH r7, [r1,#2] @ r7 = obuf[1]
586+ MUL r4, r2, r4 @ r4 = tmp0*vol_l
587+ MUL r5, r3, r5 @ r5 = tmp1*vol_r
588+
589+ ADDS r6, r4, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp0*vol_l
590+ RSCVS r6, r14,#1<<31 @ Clamp r6
591+ ADDS r7, r5, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp1*vol_r
592+ RSCVS r7, r14,#1<<31 @ Clamp r7
593+
594+ MOV r6, r6, LSR #16 @ Shift back to halfword
595+ MOV r7, r7, LSR #16 @ Shift back to halfword
596+
597+ STRH r6, [r1],#2 @ Store output value
598+ STRH r7, [r1],#2 @ Store output value
599+
600+ SUBS r0,r0,#2 @ len -= 2
601+ BGT CopyRate_R_loop @ and loop
602+
603+ LDMFD r13!,{r4-r7,PC}
604+
605+ARM_SimpleRate_M:
606+ @ r0 = AudioStream &input
607+ @ r1 = input.readBuffer
608+ @ r2 = input->sr
609+ @ r3 = obuf
610+ @ <> = osamp
611+ @ <> = vol_l
612+ @ <> = vol_r
613+ MOV r12,r13
614+ STMFD r13!,{r0-r2,r4-r8,r10-r11,r14}
615+ LDMFD r12,{r11,r12,r14} @ r11= osamp
616+ @ r12= vol_l
617+ @ r14= vol_r
618+ LDMIA r2,{r0,r1,r2,r8} @ r0 = inPtr
619+ @ r1 = inLen
620+ @ r2 = opos
621+ @ r8 = opos_inc
622+ CMP r11,#0 @ if (osamp <= 0)
623+ BLE SimpleRate_M_end @ bale
624+ MOV r10,#0
625+ ORR r12,r12,r12,LSL #8 @ r12= vol_l as 16 bits
626+ ORR r14,r14,r14,LSL #8 @ r14= vol_r as 16 bits
627+SimpleRate_M_loop:
628+ SUBS r1, r1, #1 @ r1 = inLen -= 1
629+ BLT SimpleRate_M_read
630+ SUBS r2, r2, #1 @ r2 = opos--
631+ ADDGE r0, r0, #2 @ if (r2 >= 0) { sr.inPtr++
632+ BGE SimpleRate_M_loop @ and loop }
633+SimpleRate_M_read_return:
634+ LDRSH r5, [r0],#2 @ r5 = tmp1 = *inPtr++
635+ LDRSH r6, [r3] @ r6 = obuf[0]
636+ LDRSH r7, [r3,#2] @ r7 = obuf[1]
637+ ADD r2, r2, r8 @ r2 = opos += opos_inc
638+ MUL r4, r12,r5 @ r4 = tmp0*vol_l
639+ MUL r5, r14,r5 @ r5 = tmp1*vol_r
640+
641+ ADDS r6, r4, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp0*vol_l
642+ RSCVS r6, r10,#1<<31 @ Clamp r6
643+ ADDS r7, r5, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp1*vol_r
644+ RSCVS r7, r10,#1<<31 @ Clamp r7
645+
646+ MOV r6, r6, LSR #16 @ Shift back to halfword
647+ MOV r7, r7, LSR #16 @ Shift back to halfword
648+
649+ STRH r6, [r3],#2 @ Store output value
650+ STRH r7, [r3],#2 @ Store output value
651+
652+ SUBS r11,r11,#1 @ len--
653+ BGT SimpleRate_M_loop @ and loop
654+SimpleRate_M_end:
655+ LDR r14,[r13,#8] @ r14 = sr
656+ ADD r13,r13,#12 @ Skip over r0-r2 on stack
657+ STMIA r14,{r0,r1,r2} @ Store back updated values
658+ LDMFD r13!,{r4-r8,r10-r11,PC}
659+SimpleRate_M_read:
660+ LDR r0, [r13,#4*2] @ r0 = sr
661+ ADD r0, r0, #16 @ r0 = inPtr = inBuf
662+ STMFD r13!,{r0,r2-r3,r12,r14}
663+
664+ MOV r1, r0 @ r1 = inBuf
665+ LDR r0, [r13,#4*5] @ r0 = AudioStream & input
666+ MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
667+
668+ @ Calling back into C++ here. WinCE is fairly easy about such things
669+ @ but other OS are more awkward. r9 is preserved for Symbian, and
670+ @ we have 3+8+5 = 16 things on the stack (an even number).
671+ MOV r14,PC
672+ LDR PC,[r13,#4*6] @ inLen = input.readBuffer(inBuf,512)
673+ SUBS r1, r0, #1 @ r1 = inLen-1
674+ LDMFD r13!,{r0,r2-r3,r12,r14}
675+ BLT SimpleRate_M_end
676+ SUBS r2, r2, #1 @ r2 = opos--
677+ ADDGE r0, r0, #2 @ if (r2 >= 0) { sr.inPtr++
678+ BGE SimpleRate_M_loop @ and loop }
679+ B SimpleRate_M_read_return
680+
681+
682+ARM_SimpleRate_S:
683+ @ r0 = AudioStream &input
684+ @ r1 = input.readBuffer
685+ @ r2 = input->sr
686+ @ r3 = obuf
687+ @ <> = osamp
688+ @ <> = vol_l
689+ @ <> = vol_r
690+ MOV r12,r13
691+ STMFD r13!,{r0-r2,r4-r8,r10-r11,r14}
692+ LDMFD r12,{r11,r12,r14} @ r11= osamp
693+ @ r12= vol_l
694+ @ r14= vol_r
695+ LDMIA r2,{r0,r1,r2,r8} @ r0 = inPtr
696+ @ r1 = inLen
697+ @ r2 = opos
698+ @ r8 = opos_inc
699+ CMP r11,#0 @ if (osamp <= 0)
700+ BLE SimpleRate_S_end @ bale
701+ MOV r10,#0
702+ ORR r12,r12,r12,LSL #8 @ r12= vol_l as 16 bits
703+ ORR r14,r14,r14,LSL #8 @ r14= vol_r as 16 bits
704+SimpleRate_S_loop:
705+ SUBS r1, r1, #2 @ r1 = inLen -= 2
706+ BLT SimpleRate_S_read
707+ SUBS r2, r2, #1 @ r2 = opos--
708+ ADDGE r0, r0, #4 @ if (r2 >= 0) { sr.inPtr += 2
709+ BGE SimpleRate_S_loop @ and loop }
710+SimpleRate_S_read_return:
711+ LDRSH r4, [r0],#2 @ r4 = tmp0 = *inPtr++
712+ LDRSH r5, [r0],#2 @ r5 = tmp1 = *inPtr++
713+ LDRSH r6, [r3] @ r6 = obuf[0]
714+ LDRSH r7, [r3,#2] @ r7 = obuf[1]
715+ ADD r2, r2, r8 @ r2 = opos += opos_inc
716+ MUL r4, r12,r4 @ r5 = tmp0*vol_l
717+ MUL r5, r14,r5 @ r6 = tmp1*vol_r
718+
719+ ADDS r6, r4, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp0*vol_l
720+ RSCVS r6, r10,#1<<31 @ Clamp r6
721+ ADDS r7, r5, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp1*vol_r
722+ RSCVS r7, r10,#1<<31 @ Clamp r7
723+
724+ MOV r6, r6, LSR #16 @ Shift back to halfword
725+ MOV r7, r7, LSR #16 @ Shift back to halfword
726+
727+ STRH r6, [r3],#2 @ Store output value
728+ STRH r7, [r3],#2 @ Store output value
729+
730+ SUBS r11,r11,#1 @ osamp--
731+ BGT SimpleRate_S_loop @ and loop
732+SimpleRate_S_end:
733+ LDR r14,[r13,#8] @ r14 = sr
734+ ADD r13,r13,#12 @ skip over r0-r2 on stack
735+ STMIA r14,{r0,r1,r2} @ store back updated values
736+ LDMFD r13!,{r4-r8,r10-r11,PC}
737+SimpleRate_S_read:
738+ LDR r0, [r13,#4*2] @ r0 = sr
739+ ADD r0, r0, #16 @ r0 = inPtr = inBuf
740+ STMFD r13!,{r0,r2-r3,r12,r14}
741+
742+ MOV r1, r0 @ r1 = inBuf
743+ LDR r0, [r13,#4*5] @ r0 = AudioStream & input
744+ MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
745+
746+ @ Calling back into C++ here. WinCE is fairly easy about such things
747+ @ but other OS are more awkward. r9 is preserved for Symbian, and
748+ @ we have 3+8+5 = 16 things on the stack (an even number).
749+ MOV r14,PC
750+ LDR PC,[r13,#4*6] @ inLen = input.readBuffer(inBuf,512)
751+ SUBS r1, r0, #2 @ r1 = inLen-2
752+ LDMFD r13!,{r0,r2-r3,r12,r14}
753+ BLT SimpleRate_S_end
754+ SUBS r2, r2, #1 @ r2 = opos--
755+ ADDGE r0, r0, #4 @ if (r2 >= 0) { sr.inPtr += 2
756+ BGE SimpleRate_S_loop @ and loop }
757+ B SimpleRate_S_read_return
758+
759+
760+
761+ARM_SimpleRate_R:
762+ @ r0 = AudioStream &input
763+ @ r1 = input.readBuffer
764+ @ r2 = input->sr
765+ @ r3 = obuf
766+ @ <> = osamp
767+ @ <> = vol_l
768+ @ <> = vol_r
769+ MOV r12,r13
770+ STMFD r13!,{r0-r2,r4-r8,r10-r11,r14}
771+ LDMFD r12,{r11,r12,r14} @ r11= osamp
772+ @ r12= vol_l
773+ @ r14= vol_r
774+ LDMIA r2,{r0,r1,r2,r8} @ r0 = inPtr
775+ @ r1 = inLen
776+ @ r2 = opos
777+ @ r8 = opos_inc
778+ CMP r11,#0 @ if (osamp <= 0)
779+ BLE SimpleRate_R_end @ bale
780+ MOV r10,#0
781+ ORR r12,r12,r12,LSL #8 @ r12= vol_l as 16 bits
782+ ORR r14,r14,r14,LSL #8 @ r14= vol_r as 16 bits
783+SimpleRate_R_loop:
784+ SUBS r1, r1, #2 @ r1 = inLen -= 2
785+ BLT SimpleRate_R_read
786+ SUBS r2, r2, #1 @ r2 = opos--
787+ ADDGE r0, r0, #4 @ if (r2 >= 0) { sr.inPtr += 2
788+ BGE SimpleRate_R_loop @ and loop }
789+SimpleRate_R_read_return:
790+ LDRSH r5, [r0],#2 @ r5 = tmp0 = *inPtr++
791+ LDRSH r4, [r0],#2 @ r4 = tmp1 = *inPtr++
792+ LDRSH r6, [r3] @ r6 = obuf[0]
793+ LDRSH r7, [r3,#2] @ r7 = obuf[1]
794+ ADD r2, r2, r8 @ r2 = opos += opos_inc
795+ MUL r4, r12,r4 @ r5 = tmp0*vol_l
796+ MUL r5, r14,r5 @ r6 = tmp1*vol_r
797+
798+ ADDS r6, r4, r6, LSL #16 @ r6 = obuf[0]<<16 + tmp0*vol_l
799+ RSCVS r6, r10,#1<<31 @ Clamp r6
800+ ADDS r7, r5, r7, LSL #16 @ r7 = obuf[1]<<16 + tmp1*vol_r
801+ RSCVS r7, r10,#1<<31 @ Clamp r7
802+
803+ MOV r6, r6, LSR #16 @ Shift back to halfword
804+ MOV r7, r7, LSR #16 @ Shift back to halfword
805+
806+ STRH r6, [r3],#2 @ Store output value
807+ STRH r7, [r3],#2 @ Store output value
808+
809+ SUBS r11,r11,#1 @ osamp--
810+ BGT SimpleRate_R_loop @ and loop
811+SimpleRate_R_end:
812+ LDR r14,[r13,#8] @ r14 = sr
813+ ADD r13,r13,#12 @ Skip over r0-r2 on stack
814+ STMIA r14,{r0,r1,r2} @ Store back updated values
815+ LDMFD r13!,{r4-r8,r10-r11,PC}
816+SimpleRate_R_read:
817+ LDR r0, [r13,#4*2] @ r0 = sr
818+ ADD r0, r0, #16 @ r0 = inPtr = inBuf
819+ STMFD r13!,{r0,r2-r3,r12,r14}
820+
821+ MOV r1, r0 @ r1 = inBuf
822+ LDR r0, [r13,#4*5] @ r0 = AudioStream & input
823+ MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
824+
825+ @ Calling back into C++ here. WinCE is fairly easy about such things
826+ @ but other OS are more awkward. r9 is preserved for Symbian, and
827+ @ we have 3+8+5 = 16 things on the stack (an even number).
828+ MOV r14,PC
829+ LDR PC,[r13,#4*6] @ inLen = input.readBuffer(inBuf,512)
830+ SUBS r1, r0, #2 @ r1 = inLen-2
831+ LDMFD r13!,{r0,r2-r3,r12,r14}
832+ BLT SimpleRate_R_end
833+ SUBS r2, r2, #1 @ r2 = opos--
834+ ADDGE r0, r0, #4 @ if (r2 >= 0) { sr.inPtr += 2
835+ BGE SimpleRate_R_loop @ and loop }
836+ B SimpleRate_R_read_return
837+
838+
839+ARM_LinearRate_M:
840+ @ r0 = AudioStream &input
841+ @ r1 = input.readBuffer
842+ @ r2 = input->sr
843+ @ r3 = obuf
844+ @ <> = osamp
845+ @ <> = vol_l
846+ @ <> = vol_r
847+ MOV r12,r13
848+ STMFD r13!,{r0-r1,r4-r11,r14}
849+ LDMFD r12,{r11,r12,r14} @ r11= osamp
850+ @ r12= vol_l
851+ @ r14= vol_r
852+ LDMIA r2,{r0,r1,r8} @ r0 = inPtr
853+ @ r1 = inLen
854+ @ r8 = opos
855+ CMP r11,#0 @ if (osamp <= 0)
856+ BLE LinearRate_M_end @ bale
857+ ORR r12,r12,r12,LSL #8 @ r12= vol_l as 16 bits
858+ ORR r14,r14,r14,LSL #8 @ r14= vol_r as 16 bits
859+ CMP r1,#0
860+ BGT LinearRate_M_part2
861+
862+ @ part1 - read input samples
863+LinearRate_M_loop:
864+ SUBS r1, r1, #1 @ r1 = inLen -= 1
865+ BLT LinearRate_M_read
866+LinearRate_M_read_return:
867+ LDR r10,[r2, #16] @ r10= icur[0,1]
868+ LDRSH r5, [r0],#2 @ r5 = tmp1 = *inPtr++
869+ SUBS r8, r8, #1 @ r8 = opos--
870+ STR r10,[r2,#20] @ ilast[0,1] = icur[0,1]
871+ STRH r5, [r2,#16] @ icur[0] = tmp1
872+ BGE LinearRate_M_loop
873+
874+ @ part2 - form output samples
875+LinearRate_M_part2:
876+ @ We are guaranteed that opos < 0 here
877+ LDRSH r6, [r2,#20] @ r6 = ilast[0]
878+ LDRSH r5, [r2,#16] @ r5 = icur[0]
879+ LDRH r4, [r2,#24] @ r4 = opos_frac
880+ LDR r10,[r2,#28] @ r10= opos_frac_inc
881+ MOV r6, r6, LSL #16 @ r6 = ilast[0]<<16
882+ SUB r5, r5, r6, ASR #16 @ r5 = icur[0] - ilast[0]
883+ ADD r6, r6, #1<<15 @ r6 = ilast[0]+1<<(FRAC_BITS-1)
884+ MLA r6, r4, r5, r6 @ r6 = (icur[0]-ilast[0])*opos_frac+ilast[0]
885+
886+ ADD r4, r4, r10 @ r4 = tmp = opos_frac+opos_inc_frac
887+ STRH r4,[r2,#24] @ opos_frac &= 65535
888+ ADD r8, r8, r4, LSR #16 @ opos += (tmp>>FRAC_BITS)
889+
890+ LDRSH r4, [r3] @ r4 = obuf[0]
891+ LDRSH r5, [r3,#2] @ r5 = obuf[1]
892+ MOV r6, r6, ASR #16 @ r6 = tmp0 = tmp1 >>= 16
893+ MUL r7, r12,r6 @ r7 = tmp0*vol_l
894+ MUL r6, r14,r6 @ r6 = tmp1*vol_r
895+
896+ ADDS r7, r7, r4, LSL #16 @ r7 = obuf[0]<<16 + tmp0*vol_l
897+ MOV r4, #0
898+ RSCVS r7, r4, #1<<31 @ Clamp r7
899+ ADDS r6, r6, r5, LSL #16 @ r6 = obuf[1]<<16 + tmp1*vol_r
900+ RSCVS r6, r4, #1<<31 @ Clamp r6
901+
902+ MOV r7, r7, LSR #16 @ Shift back to halfword
903+ MOV r6, r6, LSR #16 @ Shift back to halfword
904+
905+ LDR r5, [r2,#12] @ r5 = opos_inc
906+ STRH r7, [r3],#2 @ Store output value
907+ STRH r6, [r3],#2 @ Store output value
908+ SUBS r11, r11,#1 @ opos--
909+ BLE LinearRate_M_end @ end if needed
910+
911+ ADDS r8, r8, r5 @ r8 = opos += opos_inc
912+ BLT LinearRate_M_part2
913+ B LinearRate_M_loop
914+LinearRate_M_end:
915+ ADD r13,r13,#8
916+ STMIA r2,{r0,r1,r8}
917+ LDMFD r13!,{r4-r11,PC}
918+LinearRate_M_read:
919+ ADD r0, r2, #32 @ r0 = inPtr = inBuf
920+ STMFD r13!,{r0,r2-r3,r12,r14}
921+
922+ MOV r1, r0 @ r1 = inBuf
923+ LDR r0, [r13,#4*5] @ r0 = AudioStream & input
924+ MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
925+
926+ @ Calling back into C++ here. WinCE is fairly easy about such things
927+ @ but other OS are more awkward. r9 is preserved for Symbian, and
928+ @ we have 2+9+5 = 16 things on the stack (an even number).
929+ MOV r14,PC
930+ LDR PC,[r13,#4*6] @ inLen = input.readBuffer(inBuf,512)
931+ SUBS r1, r0, #1 @ r1 = inLen-1
932+ LDMFD r13!,{r0,r2-r3,r12,r14}
933+ BLT LinearRate_M_end
934+ B LinearRate_M_read_return
935+
936+ARM_LinearRate_S:
937+ @ r0 = AudioStream &input
938+ @ r1 = input.readBuffer
939+ @ r2 = input->sr
940+ @ r3 = obuf
941+ @ <> = osamp
942+ @ <> = vol_l
943+ @ <> = vol_r
944+ MOV r12,r13
945+ STMFD r13!,{r0-r1,r4-r11,r14}
946+ LDMFD r12,{r11,r12,r14} @ r11= osamp
947+ @ r12= vol_l
948+ @ r14= vol_r
949+ LDMIA r2,{r0,r1,r8} @ r0 = inPtr
950+ @ r1 = inLen
951+ @ r8 = opos
952+ CMP r11,#0 @ if (osamp <= 0)
953+ BLE LinearRate_S_end @ bale
954+ ORR r12,r12,r12,LSL #8 @ r12= vol_l as 16 bits
955+ ORR r14,r14,r14,LSL #8 @ r14= vol_r as 16 bits
956+ CMP r1,#0
957+ BGT LinearRate_S_part2
958+
959+ @ part1 - read input samples
960+LinearRate_S_loop:
961+ SUBS r1, r1, #2 @ r1 = inLen -= 2
962+ BLT LinearRate_S_read
963+LinearRate_S_read_return:
964+ LDR r10,[r2, #16] @ r10= icur[0,1]
965+ LDRSH r5, [r0],#2 @ r5 = tmp0 = *inPtr++
966+ LDRSH r6, [r0],#2 @ r5 = tmp1 = *inPtr++
967+ SUBS r8, r8, #1 @ r8 = opos--
968+ STR r10,[r2,#20] @ ilast[0,1] = icur[0,1]
969+ STRH r5, [r2,#16] @ icur[0] = tmp0
970+ STRH r6, [r2,#16] @ icur[1] = tmp1
971+ BGE LinearRate_S_loop
972+
973+ @ part2 - form output samples
974+LinearRate_S_part2:
975+ @ We are guaranteed that opos < 0 here
976+ LDRSH r6, [r2,#20] @ r6 = ilast[0]
977+ LDRSH r5, [r2,#16] @ r5 = icur[0]
978+ LDRH r4, [r2,#24] @ r4 = opos_frac
979+ MOV r6, r6, LSL #16 @ r6 = ilast[0]<<16
980+ SUB r5, r5, r6, ASR #16 @ r5 = icur[0] - ilast[0]
981+ ADD r6, r6, #1<<15 @ r6 = ilast[0]+1<<(FRAC_BITS-1)
982+ MLA r6, r4, r5, r6 @ r6 = (icur[0]-ilast[0])*opos_frac+ilast[0]
983+
984+ LDRSH r7, [r2,#22] @ r6 = ilast[1]
985+ LDRSH r5, [r2,#18] @ r5 = icur[1]
986+ LDR r10,[r2,#28] @ r10= opos_frac_inc
987+ MOV r7, r7, LSL #16 @ r7 = ilast[1]<<16
988+ SUB r5, r5, r7, ASR #16 @ r5 = icur[1] - ilast[1]
989+ ADD r7, r7, #1<<15 @ r6 = ilast[1]+1<<(FRAC_BITS-1)
990+ MLA r7, r4, r5, r7 @ r6 = (icur[1]-ilast[1])*opos_frac+ilast[1]
991+
992+ ADD r4, r4, r10 @ r4 = tmp = opos_frac+opos_inc_frac
993+ STRH r4,[r2,#24] @ opos_frac &= 65535
994+ ADD r8, r8, r4, LSR #16 @ opos += (tmp>>FRAC_BITS)
995+
996+ LDRSH r4, [r3] @ r4 = obuf[0]
997+ LDRSH r5, [r3,#2] @ r5 = obuf[1]
998+ MOV r7, r7, ASR #16 @ r7 = tmp0 >>= 16
999+ MOV r6, r6, ASR #16 @ r6 = tmp1 >>= 16
1000+ MUL r7, r12,r7 @ r7 = tmp0*vol_l
1001+ MUL r6, r14,r6 @ r6 = tmp1*vol_r
1002+
1003+ ADDS r7, r7, r4, LSL #16 @ r7 = obuf[0]<<16 + tmp0*vol_l
1004+ MOV r4, #0
1005+ RSCVS r7, r4, #1<<31 @ Clamp r7
1006+ ADDS r6, r6, r5, LSL #16 @ r6 = obuf[1]<<16 + tmp1*vol_r
1007+ RSCVS r6, r4, #1<<31 @ Clamp r6
1008+
1009+ MOV r7, r7, LSR #16 @ Shift back to halfword
1010+ MOV r6, r6, LSR #16 @ Shift back to halfword
1011+
1012+ LDR r5, [r2,#12] @ r5 = opos_inc
1013+ STRH r7, [r3],#2 @ Store output value
1014+ STRH r6, [r3],#2 @ Store output value
1015+ SUBS r11, r11,#1 @ opos--
1016+ BLE LinearRate_S_end @ and loop
1017+
1018+ ADDS r8, r8, r5 @ r8 = opos += opos_inc
1019+ BLT LinearRate_S_part2
1020+ B LinearRate_S_loop
1021+LinearRate_S_end:
1022+ ADD r13,r13,#8
1023+ STMIA r2,{r0,r1,r8}
1024+ LDMFD r13!,{r4-r11,PC}
1025+LinearRate_S_read:
1026+ ADD r0, r2, #32 @ r0 = inPtr = inBuf
1027+ STMFD r13!,{r0,r2-r3,r12,r14}
1028+
1029+ MOV r1, r0 @ r1 = inBuf
1030+ LDR r0, [r13,#4*5] @ r0 = AudioStream & input
1031+ MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
1032+
1033+ @ Calling back into C++ here. WinCE is fairly easy about such things
1034+ @ but other OS are more awkward. r9 is preserved for Symbian, and
1035+ @ we have 2+9+5 = 16 things on the stack (an even number).
1036+ MOV r14,PC
1037+ LDR PC,[r13,#4*6] @ inLen = input.readBuffer(inBuf,512)
1038+ SUBS r1, r0, #2 @ r1 = inLen-2
1039+ LDMFD r13!,{r0,r2-r3,r12,r14}
1040+ BLT LinearRate_S_end
1041+ B LinearRate_S_read_return
1042+
1043+ARM_LinearRate_R:
1044+ @ r0 = AudioStream &input
1045+ @ r1 = input.readBuffer
1046+ @ r2 = input->sr
1047+ @ r3 = obuf
1048+ @ <> = osamp
1049+ @ <> = vol_l
1050+ @ <> = vol_r
1051+ MOV r12,r13
1052+ STMFD r13!,{r0-r1,r4-r11,r14}
1053+ LDMFD r12,{r11,r12,r14} @ r11= osamp
1054+ @ r12= vol_l
1055+ @ r14= vol_r
1056+ LDMIA r2,{r0,r1,r8} @ r0 = inPtr
1057+ @ r1 = inLen
1058+ @ r8 = opos
1059+ CMP r11,#0 @ if (osamp <= 0)
1060+ BLE LinearRate_R_end @ bale
1061+ ORR r12,r12,r12,LSL #8 @ r12= vol_l as 16 bits
1062+ ORR r14,r14,r14,LSL #8 @ r14= vol_r as 16 bits
1063+ CMP r1,#0
1064+ BGT LinearRate_R_part2
1065+
1066+ @ part1 - read input samples
1067+LinearRate_R_loop:
1068+ SUBS r1, r1, #2 @ r1 = inLen -= 2
1069+ BLT LinearRate_R_read
1070+LinearRate_R_read_return:
1071+ LDR r10,[r2, #16] @ r10= icur[0,1]
1072+ LDRSH r5, [r0],#2 @ r5 = tmp0 = *inPtr++
1073+ LDRSH r6, [r0],#2 @ r5 = tmp1 = *inPtr++
1074+ SUBS r8, r8, #1 @ r8 = opos--
1075+ STR r10,[r2,#20] @ ilast[0,1] = icur[0,1]
1076+ STRH r5, [r2,#16] @ icur[0] = tmp0
1077+ STRH r6, [r2,#16] @ icur[1] = tmp1
1078+ BGE LinearRate_R_loop
1079+
1080+ @ part2 - form output samples
1081+LinearRate_R_part2:
1082+ @ We are guaranteed that opos < 0 here
1083+ LDRSH r6, [r2,#20] @ r6 = ilast[0]
1084+ LDRSH r5, [r2,#16] @ r5 = icur[0]
1085+ LDRH r4, [r2,#24] @ r4 = opos_frac
1086+ MOV r6, r6, LSL #16 @ r6 = ilast[0]<<16
1087+ SUB r5, r5, r6, ASR #16 @ r5 = icur[0] - ilast[0]
1088+ ADD r6, r6, #1<<15 @ r6 = ilast[0]+1<<(FRAC_BITS-1)
1089+ MLA r6, r4, r5, r6 @ r6 = (icur[0]-ilast[0])*opos_frac+ilast[0]
1090+
1091+ LDRSH r7, [r2,#22] @ r6 = ilast[1]
1092+ LDRSH r5, [r2,#18] @ r5 = icur[1]
1093+ LDR r10,[r2,#28] @ r10= opos_frac_inc
1094+ MOV r7, r7, LSL #16 @ r7 = ilast[1]<<16
1095+ SUB r5, r5, r7, ASR #16 @ r5 = icur[1] - ilast[1]
1096+ ADD r7, r7, #1<<15 @ r6 = ilast[1]+1<<(FRAC_BITS-1)
1097+ MLA r7, r4, r5, r7 @ r6 = (icur[1]-ilast[1])*opos_frac+ilast[1]
1098+
1099+ ADD r4, r4, r10 @ r4 = tmp = opos_frac+opos_inc_frac
1100+ STRH r4,[r2,#24] @ opos_frac &= 65535
1101+ ADD r8, r8, r4, LSR #16 @ opos += (tmp>>FRAC_BITS)
1102+
1103+ LDRSH r4, [r3] @ r4 = obuf[0]
1104+ LDRSH r5, [r3,#2] @ r5 = obuf[1]
1105+ MOV r7, r7, ASR #16 @ r7 = tmp0 >>= 16
1106+ MOV r6, r6, ASR #16 @ r6 = tmp1 >>= 16
1107+ MUL r7, r12,r7 @ r7 = tmp0*vol_l
1108+ MUL r6, r14,r6 @ r6 = tmp1*vol_r
1109+
1110+ ADDS r7, r7, r4, LSL #16 @ r7 = obuf[0]<<16 + tmp0*vol_l
1111+ MOV r4, #0
1112+ RSCVS r7, r4, #1<<31 @ Clamp r7
1113+ ADDS r6, r6, r5, LSL #16 @ r6 = obuf[1]<<16 + tmp1*vol_r
1114+ RSCVS r6, r4, #1<<31 @ Clamp r6
1115+
1116+ MOV r7, r7, LSR #16 @ Shift back to halfword
1117+ MOV r6, r6, LSR #16 @ Shift back to halfword
1118+
1119+ LDR r5, [r2,#12] @ r5 = opos_inc
1120+ STRH r6, [r3],#2 @ Store output value
1121+ STRH r7, [r3],#2 @ Store output value
1122+ SUBS r11, r11,#1 @ opos--
1123+ BLE LinearRate_R_end @ and loop
1124+
1125+ ADDS r8, r8, r5 @ r8 = opos += opos_inc
1126+ BLT LinearRate_R_part2
1127+ B LinearRate_R_loop
1128+LinearRate_R_end:
1129+ ADD r13,r13,#8
1130+ STMIA r2,{r0,r1,r8}
1131+ LDMFD r13!,{r4-r11,PC}
1132+LinearRate_R_read:
1133+ ADD r0, r2, #32 @ r0 = inPtr = inBuf
1134+ STMFD r13!,{r0,r2-r3,r12,r14}
1135+
1136+ MOV r1, r0 @ r1 = inBuf
1137+ LDR r0, [r13,#4*5] @ r0 = AudioStream & input
1138+ MOV r2, #512 @ r2 = ARRAYSIZE(inBuf)
1139+
1140+ @ Calling back into C++ here. WinCE is fairly easy about such things
1141+ @ but other OS are more awkward. r9 is preserved for Symbian, and
1142+ @ we have 2+9+5 = 16 things on the stack (an even number).
1143+ MOV r14,PC
1144+ LDR PC,[r13,#4*6] @ inLen = input.readBuffer(inBuf,512)
1145+ SUBS r1, r0, #2 @ r1 = inLen-2
1146+ LDMFD r13!,{r0,r2-r3,r12,r14}
1147+ BLT LinearRate_R_end
1148+ B LinearRate_R_read_return
1149
1150Property changes on: sound/rate_arm_asm.s
1151___________________________________________________________________
1152Name: svn:executable
1153 + *
1154