Ticket #8661: diff

File diff, 31.5 KB (added by SF/robinwatts, 13 years ago)

ARM asm version of sound rate conversion/mixing code

  • sound/rate_arm.cpp

     
     1/* ScummVM - Scumm Interpreter
     2 * Copyright (C) 2001-2006 The ScummVM project
     3 *
     4 * This program is free software; you can redistribute it and/or
     5 * modify it under the terms of the GNU General Public License
     6 * as published by the Free Software Foundation; either version 2
     7 * of the License, or (at your option) any later version.
     8
     9 * This program is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13
     14 * You should have received a copy of the GNU General Public License
     15 * along with this program; if not, write to the Free Software
     16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     17 *
     18 * $URL: https://svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/sound/rate.cpp $
     19 * $Id: rate.cpp 25790 2007-02-22 16:36:03Z fingolfin $
     20 *
     21 */
     22
     23/*
     24 * The code in this file is based on code with Copyright 1998 Fabrice Bellard
     25 * Fabrice original code is part of SoX (http://sox.sourceforge.net).
     26 * Max Horn adapted that code to the needs of ScummVM and rewrote it partial,
     27 * in the process removing any use of floating point arithmetic. Various other
     28 * improvments over the original code were made.
     29 */
     30
     31#include "common/stdafx.h"
     32#include "sound/audiostream.h"
     33#include "sound/rate.h"
     34#include "sound/mixer.h"
     35#include "common/util.h"
     36
     37namespace Audio {
     38
     39/**
     40 * The precision of the fractional computations used by the rate converter.
     41 * Normally you should never have to modify this value.
     42 */
     43#define FRAC_BITS 16
     44
     45/**
     46 * The size of the intermediate input cache. Bigger values may increase
     47 * performance, but only until some point (depends largely on cache size,
     48 * target processor and various other factors), at which it will decrease
     49 * again.
     50 */
     51#define INTERMEDIATE_BUFFER_SIZE 512
     52
     53
     54/**
     55 * Audio rate converter based on simple resampling. Used when no
     56 * interpolation is required.
     57 *
     58 * Limited to sampling frequency <= 65535 Hz.
     59 */
     60typedef struct {
     61        const st_sample_t *inPtr;
     62        int inLen;
     63
     64        /** position of how far output is ahead of input */
     65        /** Holds what would have been opos-ipos */
     66        long opos;
     67
     68        /** fractional position increment in the output stream */
     69        long opos_inc;
     70
     71        st_sample_t inBuf[INTERMEDIATE_BUFFER_SIZE];
     72} SimpleRateDetails;
     73
     74template<bool stereo, bool reverseStereo>
     75class SimpleRateConverter : public RateConverter {
     76protected:
     77        SimpleRateDetails  sr;
     78public:
     79        SimpleRateConverter(st_rate_t inrate, st_rate_t outrate);
     80        int flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r);
     81        int drain(st_sample_t *obuf, st_size_t osamp, st_volume_t vol) {
     82                return (ST_SUCCESS);
     83        }
     84};
     85
     86
     87/*
     88 * Prepare processing.
     89 */
     90template<bool stereo, bool reverseStereo>
     91SimpleRateConverter<stereo, reverseStereo>::SimpleRateConverter(st_rate_t inrate, st_rate_t outrate) {
     92        if (inrate == outrate) {
     93                error("Input and Output rates must be different to use rate effect");
     94        }
     95
     96        if ((inrate % outrate) != 0) {
     97                error("Input rate must be a multiple of Output rate to use rate effect");
     98        }
     99
     100        if (inrate >= 65536 || outrate >= 65536) {
     101                error("rate effect can only handle rates < 65536");
     102        }
     103
     104        sr.opos = 1;
     105
     106        /* increment */
     107        sr.opos_inc = inrate / outrate;
     108
     109        sr.inLen = 0;
     110}
     111
     112extern "C" void ARM_SimpleRate_M(AudioStream       &input,
     113                                 int (*fn)(Audio::AudioStream&,int16*,int),
     114                                 SimpleRateDetails *sr,
     115                                 st_sample_t       *obuf,
     116                                 st_size_t          osamp,
     117                                 st_volume_t        vol_l,
     118                                 st_volume_t        vol_r);
     119
     120extern "C" void ARM_SimpleRate_S(AudioStream       &input,
     121                                 int (*fn)(Audio::AudioStream&,int16*,int),
     122                                 SimpleRateDetails *sr,
     123                                 st_sample_t       *obuf,
     124                                 st_size_t          osamp,
     125                                 st_volume_t        vol_l,
     126                                 st_volume_t        vol_r);
     127
     128extern "C" void ARM_SimpleRate_R(AudioStream       &input,
     129                                 int (*fn)(Audio::AudioStream&,int16*,int),
     130                                 SimpleRateDetails *sr,
     131                                 st_sample_t       *obuf,
     132                                 st_size_t          osamp,
     133                                 st_volume_t        vol_l,
     134                                 st_volume_t        vol_r);
     135
     136extern "C" int SimpleRate_readFudge(Audio::AudioStream &input,
     137                                    int16 *a, int b)
     138{
     139  return input.readBuffer(a, b);
     140}
     141
     142template<bool stereo, bool reverseStereo>
     143int SimpleRateConverter<stereo, reverseStereo>::flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) {
     144
     145        if (!stereo) {
     146                ARM_SimpleRate_M(input,
     147                                 &SimpleRate_readFudge,
     148                                 &sr,
     149                                 obuf, osamp, vol_l, vol_r);
     150        }
     151        else if (reverseStereo)
     152        {
     153                ARM_SimpleRate_R(input,
     154                                 &SimpleRate_readFudge,
     155                                 &sr,
     156                                 obuf, osamp, vol_l, vol_r);
     157        }
     158        else
     159        {
     160                ARM_SimpleRate_S(input,
     161                                 &SimpleRate_readFudge,
     162                                 &sr,
     163                                 obuf, osamp, vol_l, vol_r);
     164        }
     165        return (ST_SUCCESS);
     166}
     167
     168/**
     169 * Audio rate converter based on simple linear Interpolation.
     170 *
     171 * The use of fractional increment allows us to use no buffer. It
     172 * avoid the problems at the end of the buffer we had with the old
     173 * method which stored a possibly big buffer of size
     174 * lcm(in_rate,out_rate).
     175 *
     176 * Limited to sampling frequency <= 65535 Hz.
     177 */
     178
     179typedef struct {
     180        const st_sample_t *inPtr;
     181        int inLen;
     182
     183        /** position of how far output is ahead of input */
     184        /** Holds what would have been opos-ipos */
     185        long opos;
     186
     187        /** integer position increment in the output stream */
     188        long opos_inc;
     189
     190        /** current sample(s) in the input stream (left/right channel) */
     191        st_sample_t icur[2];
     192        /** last sample(s) in the input stream (left/right channel) */
     193        st_sample_t ilast[2];
     194
     195        /** fractional position in the output stream */
     196        long opos_frac;
     197
     198        /** fractional position increment in the output stream */
     199        long opos_inc_frac;
     200
     201        st_sample_t inBuf[INTERMEDIATE_BUFFER_SIZE];
     202} LinearRateDetails;
     203
     204extern "C" void ARM_LinearRate_M(AudioStream       &input,
     205                                 int (*fn)(Audio::AudioStream&,int16*,int),
     206                                 LinearRateDetails *lr,
     207                                 st_sample_t       *obuf,
     208                                 st_size_t          osamp,
     209                                 st_volume_t        vol_l,
     210                                 st_volume_t        vol_r);
     211
     212extern "C" void ARM_LinearRate_S(AudioStream       &input,
     213                                 int (*fn)(Audio::AudioStream&,int16*,int),
     214                                 LinearRateDetails *lr,
     215                                 st_sample_t       *obuf,
     216                                 st_size_t          osamp,
     217                                 st_volume_t        vol_l,
     218                                 st_volume_t        vol_r);
     219
     220extern "C" void ARM_LinearRate_R(AudioStream       &input,
     221                                 int (*fn)(Audio::AudioStream&,int16*,int),
     222                                 LinearRateDetails *lr,
     223                                 st_sample_t       *obuf,
     224                                 st_size_t          osamp,
     225                                 st_volume_t        vol_l,
     226                                 st_volume_t        vol_r);
     227
     228template<bool stereo, bool reverseStereo>
     229class LinearRateConverter : public RateConverter {
     230protected:
     231        LinearRateDetails lr;
     232
     233public:
     234        LinearRateConverter(st_rate_t inrate, st_rate_t outrate);
     235        int flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r);
     236        int drain(st_sample_t *obuf, st_size_t osamp, st_volume_t vol) {
     237                return (ST_SUCCESS);
     238        }
     239};
     240
     241
     242/*
     243 * Prepare processing.
     244 */
     245template<bool stereo, bool reverseStereo>
     246LinearRateConverter<stereo, reverseStereo>::LinearRateConverter(st_rate_t inrate, st_rate_t outrate) {
     247        unsigned long incr;
     248
     249        if (inrate == outrate) {
     250                error("Input and Output rates must be different to use rate effect");
     251        }
     252
     253        if (inrate >= 65536 || outrate >= 65536) {
     254                error("rate effect can only handle rates < 65536");
     255        }
     256
     257        lr.opos_frac = 0;
     258        lr.opos = 1;
     259
     260        /* increment */
     261        incr = (inrate << FRAC_BITS) / outrate;
     262
     263        lr.opos_inc_frac = incr & ((1UL << FRAC_BITS) - 1);
     264        lr.opos_inc = incr >> FRAC_BITS;
     265
     266        lr.ilast[0] = lr.ilast[1] = 0;
     267        lr.icur[0] = lr.icur[1] = 0;
     268
     269        lr.inLen = 0;
     270}
     271
     272/*
     273 * Processed signed long samples from ibuf to obuf.
     274 * Return number of samples processed.
     275 */
     276template<bool stereo, bool reverseStereo>
     277int LinearRateConverter<stereo, reverseStereo>::flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) {
     278
     279        if (!stereo) {
     280                ARM_LinearRate_M(input,
     281                                 &SimpleRate_readFudge,
     282                                 &lr,
     283                                 obuf, osamp, vol_l, vol_r);
     284        }
     285        else if (reverseStereo)
     286        {
     287                ARM_LinearRate_R(input,
     288                                 &SimpleRate_readFudge,
     289                                 &lr,
     290                                 obuf, osamp, vol_l, vol_r);
     291        }
     292        else
     293        {
     294                ARM_LinearRate_S(input,
     295                                 &SimpleRate_readFudge,
     296                                 &lr,
     297                                 obuf, osamp, vol_l, vol_r);
     298        }
     299        return (ST_SUCCESS);
     300}
     301
     302
     303#pragma mark -
     304
     305
     306/**
     307 * Simple audio rate converter for the case that the inrate equals the outrate.
     308 */
     309extern "C" void ARM_CopyRate_M(st_size_t    len,
     310                               st_sample_t *obuf,
     311                               st_volume_t  vol_l,
     312                               st_volume_t  vol_r,
     313                               st_sample_t *_buffer);
     314
     315extern "C" void ARM_CopyRate_S(st_size_t    len,
     316                               st_sample_t *obuf,
     317                               st_volume_t  vol_l,
     318                               st_volume_t  vol_r,
     319                               st_sample_t *_buffer);
     320
     321extern "C" void ARM_CopyRate_R(st_size_t    len,
     322                               st_sample_t *obuf,
     323                               st_volume_t  vol_l,
     324                               st_volume_t  vol_r,
     325                               st_sample_t *_buffer);
     326
     327
     328template<bool stereo, bool reverseStereo>
     329class CopyRateConverter : public RateConverter {
     330        st_sample_t *_buffer;
     331        st_size_t _bufferSize;
     332public:
     333        CopyRateConverter() : _buffer(0), _bufferSize(0) {}
     334        ~CopyRateConverter() {
     335                free(_buffer);
     336        }
     337
     338        virtual int flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) {
     339                assert(input.isStereo() == stereo);
     340
     341                st_sample_t *ptr;
     342                st_size_t len;
     343
     344                if (stereo)
     345                        osamp *= 2;
     346
     347                // Reallocate temp buffer, if necessary
     348                if (osamp > _bufferSize) {
     349                        free(_buffer);
     350                        _buffer = (st_sample_t *)malloc(osamp * 2);
     351                        _bufferSize = osamp;
     352                }
     353
     354fprintf(stderr, "Copy %d %d\n", stereo, reverseStereo);
     355                // Read up to 'osamp' samples into our temporary buffer
     356                len = input.readBuffer(_buffer, osamp);
     357                if (len <= 0)
     358                        return (ST_SUCCESS);
     359
     360                // Mix the data into the output buffer
     361                if (stereo && reverseStereo)
     362                        ARM_CopyRate_R(len, obuf, vol_l, vol_r, _buffer);
     363                else if (stereo)
     364                        ARM_CopyRate_S(len, obuf, vol_l, vol_r, _buffer);
     365                else
     366                        ARM_CopyRate_M(len, obuf, vol_l, vol_r, _buffer);
     367
     368                return (ST_SUCCESS);
     369        }
     370        virtual int drain(st_sample_t *obuf, st_size_t osamp, st_volume_t vol) {
     371                return (ST_SUCCESS);
     372        }
     373};
     374
     375
     376#pragma mark -
     377
     378
     379/**
     380 * Create and return a RateConverter object for the specified input and output rates.
     381 */
     382RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate, bool stereo, bool reverseStereo) {
     383        if (inrate != outrate) {
     384                if ((inrate % outrate) == 0) {
     385                        if (stereo) {
     386                                if (reverseStereo)
     387                                        return new SimpleRateConverter<true, true>(inrate, outrate);
     388                                else
     389                                        return new SimpleRateConverter<true, false>(inrate, outrate);
     390                        } else
     391                                return new SimpleRateConverter<false, false>(inrate, outrate);
     392                } else {
     393                        if (stereo) {
     394                                if (reverseStereo)
     395                                        return new LinearRateConverter<true, true>(inrate, outrate);
     396                                else
     397                                        return new LinearRateConverter<true, false>(inrate, outrate);
     398                        } else
     399                                return new LinearRateConverter<false, false>(inrate, outrate);
     400                 }
     401        } else {
     402                if (stereo) {
     403                        if (reverseStereo)
     404                                return new CopyRateConverter<true, true>();
     405                        else
     406                                return new CopyRateConverter<true, false>();
     407                } else
     408                        return new CopyRateConverter<false, false>();
     409        }
     410}
     411
     412} // End of namespace Audio
  • sound/rate_arm_asm.s

    Property changes on: sound/rate_arm.cpp
    ___________________________________________________________________
    Name: svn:executable
       + *
    
     
     1@ ScummVM Scumm Interpreter
     2@ Copyright (C) 2007 The ScummVM project
     3@
     4@ This program is free software@ you can redistribute it and/or
     5@ modify it under the terms of the GNU General Public License
     6@ as published by the Free Software Foundation@ either version 2
     7@ of the License, or (at your option) any later version.
     8@
     9@ This program is distributed in the hope that it will be useful,
     10@ but WITHOUT ANY WARRANTY@ without even the implied warranty of
     11@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12@ GNU General Public License for more details.
     13@
     14@ You should have received a copy of the GNU General Public License
     15@ along with this program@ if not, write to the Free Software
     16@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     17@
     18@ $URL: $
     19@ $Id:  $
     20@
     21@ @author Robin Watts (robin@wss.co.uk)
     22
     23        .text
     24
     25        .global ARM_CopyRate_M
     26        .global ARM_CopyRate_S
     27        .global ARM_CopyRate_R
     28        .global ARM_SimpleRate_M
     29        .global ARM_SimpleRate_S
     30        .global ARM_SimpleRate_R
     31        .global ARM_LinearRate_M
     32        .global ARM_LinearRate_S
     33        .global ARM_LinearRate_R
     34
     35ARM_CopyRate_M:
     36        @ r0 = len
     37        @ r1 = obuf
     38        @ r2 = vol_l
     39        @ r3 = vol_r
     40        @ <> = ptr
     41        LDR     r12,[r13]
     42        STMFD   r13!,{r4-r7,r14}
     43
     44        MOV     r14,#0          @ r14= 0
     45        MOV     r2,r2,LSL #8
     46        MOV     r3,r3,LSL #8
     47CopyRate_M_loop:
     48        LDRSH   r5, [r12], #2   @ r5 = tmp0 = tmp1 = *ptr++
     49        LDRSH   r6, [r1]        @ r6 = obuf[0]
     50        LDRSH   r7, [r1, #2]    @ r7 = obuf[1]
     51        MUL     r4, r2, r5      @ r4 = tmp0*vol_l
     52        MUL     r5, r3, r5      @ r5 = tmp1*vol_r
     53
     54        ADDS    r6, r4, r6, LSL #16
     55        RSCVS   r6, r14,#1<<31
     56        ADDS    r7, r5, r7, LSL #16
     57        RSCVS   r7, r14,#1<<31
     58
     59        MOV     r6, r6, LSR #16
     60        MOV     r7, r7, LSR #16
     61
     62        STRH    r6, [r1], #2
     63        STRH    r7, [r1], #2
     64
     65        SUBS    r0,r0,#1
     66        BGT     CopyRate_M_loop
     67
     68        LDMFD   r13!,{r4-r7,PC}
     69
     70ARM_CopyRate_S:
     71        @ r0 = len
     72        @ r1 = obuf
     73        @ r2 = vol_l
     74        @ r3 = vol_r
     75        @ <> = ptr
     76        LDR     r12,[r13]
     77        STMFD   r13!,{r4-r7,r14}
     78
     79        MOV     r14,#0          @ r14= 0
     80        MOV     r2,r2,LSL #8
     81        MOV     r3,r3,LSL #8
     82CopyRate_S_loop:
     83        LDRSH   r4, [r12],#2    @ r4 = tmp0 = *ptr++
     84        LDRSH   r5, [r12],#2    @ r5 = tmp1 = *ptr++
     85        LDRSH   r6, [r1]        @ r6 = obuf[0]
     86        LDRSH   r7, [r1,#2]     @ r7 = obuf[1]
     87        MUL     r4, r2, r4      @ r5 = tmp0*vol_l
     88        MUL     r5, r3, r5      @ r6 = tmp1*vol_r
     89
     90        ADDS    r6, r4, r6, LSL #16
     91        RSCVS   r6, r14,#1<<31
     92        ADDS    r7, r5, r7, LSL #16
     93        RSCVS   r7, r14,#1<<31
     94
     95        MOV     r6, r6, LSR #16
     96        MOV     r7, r7, LSR #16
     97
     98        STRH    r6, [r1],#2
     99        STRH    r7, [r1],#2
     100
     101        SUBS    r0,r0,#2
     102        BGT     CopyRate_S_loop
     103
     104        LDMFD   r13!,{r4-r7,PC}
     105
     106ARM_CopyRate_R:
     107        @ r0 = len
     108        @ r1 = obuf
     109        @ r2 = vol_l
     110        @ r3 = vol_r
     111        @ <> = ptr
     112        LDR     r12,[r13]
     113        STMFD   r13!,{r4-r7,r14}
     114
     115        MOV     r14,#0          @ r14= 0
     116        MOV     r2,r2,LSL #8
     117        MOV     r3,r3,LSL #8
     118CopyRate_R_loop:
     119        LDRSH   r5, [r12],#2    @ r5 = tmp1 = *ptr++
     120        LDRSH   r4, [r12],#2    @ r4 = tmp0 = *ptr++
     121        LDRSH   r6, [r1]        @ r6 = obuf[0]
     122        LDRSH   r7, [r1,#2]     @ r7 = obuf[1]
     123        MUL     r4, r2, r4      @ r4 = tmp0*vol_l
     124        MUL     r5, r3, r5      @ r5 = tmp1*vol_r
     125
     126        ADDS    r6, r4, r6, LSL #16
     127        RSCVS   r6, r14,#1<<31
     128        ADDS    r7, r5, r7, LSL #16
     129        RSCVS   r7, r14,#1<<31
     130
     131        MOV     r6, r6, LSR #16
     132        MOV     r7, r7, LSR #16
     133
     134        STRH    r6, [r1],#2
     135        STRH    r7, [r1],#2
     136
     137        SUBS    r0,r0,#2
     138        BGT     CopyRate_R_loop
     139
     140        LDMFD   r13!,{r4-r7,PC}
     141
     142ARM_SimpleRate_M:
     143        @ r0 = AudioStream &input
     144        @ r1 = input.readBuffer
     145        @ r2 = input->sr
     146        @ r3 = obuf
     147        @ <> = osamp
     148        @ <> = vol_l
     149        @ <> = vol_r
     150        MOV     r12,r13
     151        STMFD   r13!,{r0-r2,r4-r8,r10-r11,r14}
     152        LDMFD   r12,{r11,r12,r14}       @ r11= osamp
     153                                        @ r12= vol_l
     154                                        @ r14= vol_r
     155        LDMIA   r2,{r0,r1,r2,r8}        @ r0 = inPtr
     156                                        @ r1 = inLen
     157                                        @ r2 = opos
     158                                        @ r8 = opos_inc
     159        CMP     r11,#0                  @ if (osamp <= 0)
     160        BLE     SimpleRate_M_end        @   bale
     161        MOV     r10,#0
     162        MOV     r12,r12,LSL #8
     163        MOV     r14,r14,LSL #8
     164SimpleRate_M_loop:
     165        SUBS    r1, r1, #1      @ r1 = inLen -= 1
     166        BLT     SimpleRate_M_read
     167        SUBS    r2, r2, #1      @ r2 = opos--
     168        ADDGE   r0, r0, #2      @ if (r2 >= 0) { sr.inPtr++  and loop }
     169        BGE     SimpleRate_M_loop
     170SimpleRate_M_read_return:
     171        LDRSH   r5, [r0],#2     @ r5 = tmp1 = *inPtr++
     172        LDRSH   r6, [r3]        @ r6 = obuf[0]
     173        LDRSH   r7, [r3,#2]     @ r7 = obuf[1]
     174        ADD     r2, r2, r8      @ r2 = opos += opos_inc
     175        MUL     r4, r12,r5      @ r4 = tmp0*vol_l
     176        MUL     r5, r14,r5      @ r5 = tmp1*vol_r
     177
     178        ADDS    r6, r4, r6, LSL #16
     179        RSCVS   r6, r10,#1<<31
     180        ADDS    r7, r5, r7, LSL #16
     181        RSCVS   r7, r10,#1<<31
     182
     183        MOV     r6, r6, LSR #16
     184        MOV     r7, r7, LSR #16
     185
     186        STRH    r6, [r3],#2
     187        STRH    r7, [r3],#2
     188
     189        SUBS    r11,r11,#1
     190        BGT     SimpleRate_M_loop
     191SimpleRate_M_end:
     192        LDR     r14,[r13,#8]    @ r14 = sr
     193        ADD     r13,r13,#12
     194        STMIA   r14,{r0,r1,r2}
     195        LDMFD   r13!,{r4-r8,r10-r11,PC}
     196SimpleRate_M_read:
     197        LDR     r0, [r13,#4*2]  @ r0 = sr
     198        ADD     r0, r0, #16     @ r0 = inPtr = inBuf
     199        STMFD   r13!,{r0,r2-r3,r12,r14}
     200
     201        MOV     r1, r0          @ r1 = inBuf
     202        LDR     r0, [r13,#4*5]  @ r0 = AudioStream & input
     203        MOV     r2, #512        @ r2 = ARRAYSIZE(inBuf)
     204
     205        @ Calling back into C++ here. WinCE is fairly easy about such things
     206        @ but other OS are more awkward. r9 is preserved for Symbian, and
     207        @ we have 3+8+5 = 16 things on the stack (an even number).
     208        MOV     r14,PC
     209        LDR     PC,[r13,#4*6]   @ inLen = input.readBuffer(inBuf, 512)
     210        SUBS    r1, r0, #1      @ r1 = inLen-1
     211        LDMFD   r13!,{r0,r2-r3,r12,r14}
     212        BLT     SimpleRate_M_end
     213        SUBS    r2, r2, #1      @ r2 = opos--
     214        ADDGE   r0, r0, #2      @ if (r2 >= 0) { sr.inPtr++  and loop }
     215        BGE     SimpleRate_M_loop
     216        B       SimpleRate_M_read_return
     217
     218
     219ARM_SimpleRate_S:
     220        @ r0 = AudioStream &input
     221        @ r1 = input.readBuffer
     222        @ r2 = input->sr
     223        @ r3 = obuf
     224        @ <> = osamp
     225        @ <> = vol_l
     226        @ <> = vol_r
     227        MOV     r12,r13
     228        STMFD   r13!,{r0-r2,r4-r8,r10-r11,r14}
     229        LDMFD   r12,{r11,r12,r14}       @ r11= osamp
     230                                        @ r12= vol_l
     231                                        @ r14= vol_r
     232        LDMIA   r2,{r0,r1,r2,r8}        @ r0 = inPtr
     233                                        @ r1 = inLen
     234                                        @ r2 = opos
     235                                        @ r8 = opos_inc
     236        CMP     r11,#0                  @ if (osamp <= 0)
     237        BLE     SimpleRate_S_end        @   bale
     238        MOV     r10,#0
     239        MOV     r12,r12,LSL #8
     240        MOV     r14,r14,LSL #8
     241SimpleRate_S_loop:
     242        SUBS    r1, r1, #2      @ r1 = inLen -= 2
     243        BLT     SimpleRate_S_read
     244        SUBS    r2, r2, #1      @ r2 = opos--
     245        ADDGE   r0, r0, #4      @ if (r2 >= 0) { sr.inPtr += 2  and loop }
     246        BGE     SimpleRate_S_loop
     247SimpleRate_S_read_return:
     248        LDRSH   r4, [r0],#2     @ r4 = tmp0 = *inPtr++
     249        LDRSH   r5, [r0],#2     @ r5 = tmp1 = *inPtr++
     250        LDRSH   r6, [r3]        @ r6 = obuf[0]
     251        LDRSH   r7, [r3,#2]     @ r7 = obuf[1]
     252        ADD     r2, r2, r8      @ r2 = opos += opos_inc
     253        MUL     r4, r12,r4      @ r5 = tmp0*vol_l
     254        MUL     r5, r14,r5      @ r6 = tmp1*vol_r
     255
     256        ADDS    r6, r4, r6, LSL #16
     257        RSCVS   r6, r10,#1<<31
     258        ADDS    r7, r5, r7, LSL #16
     259        RSCVS   r7, r10,#1<<31
     260
     261        MOV     r6, r6, LSR #16
     262        MOV     r7, r7, LSR #16
     263
     264        STRH    r6, [r3],#2
     265        STRH    r7, [r3],#2
     266
     267        SUBS    r11,r11,#1
     268        BGT     SimpleRate_S_loop
     269SimpleRate_S_end:
     270        LDR     r14,[r13,#8]    @ r14 = sr
     271        ADD     r13,r13,#12
     272        STMIA   r14,{r0,r1,r2}
     273        LDMFD   r13!,{r4-r8,r10-r11,PC}
     274SimpleRate_S_read:
     275        LDR     r0, [r13,#4*2]  @ r0 = sr
     276        ADD     r0, r0, #16     @ r0 = inPtr = inBuf
     277        STMFD   r13!,{r0,r2-r3,r12,r14}
     278
     279        MOV     r1, r0          @ r1 = inBuf
     280        LDR     r0, [r13,#4*5]  @ r0 = AudioStream & input
     281        MOV     r2, #512        @ r2 = ARRAYSIZE(inBuf)
     282
     283        @ Calling back into C++ here. WinCE is fairly easy about such things
     284        @ but other OS are more awkward. r9 is preserved for Symbian, and
     285        @ we have 3+8+5 = 16 things on the stack (an even number).
     286        MOV     r14,PC
     287        LDR     PC,[r13,#4*6]   @ inLen = input.readBuffer(inBuf, 512)
     288        SUBS    r1, r0, #2      @ r1 = inLen-2
     289        LDMFD   r13!,{r0,r2-r3,r12,r14}
     290        BLT     SimpleRate_S_end
     291        SUBS    r2, r2, #1      @ r2 = opos--
     292        ADDGE   r0, r0, #4      @ if (r2 >= 0) { sr.inPtr += 2  and loop }
     293        BGE     SimpleRate_S_loop
     294        B       SimpleRate_S_read_return
     295
     296
     297
     298ARM_SimpleRate_R:
     299        @ r0 = AudioStream &input
     300        @ r1 = input.readBuffer
     301        @ r2 = input->sr
     302        @ r3 = obuf
     303        @ <> = osamp
     304        @ <> = vol_l
     305        @ <> = vol_r
     306        MOV     r12,r13
     307        STMFD   r13!,{r0-r2,r4-r8,r10-r11,r14}
     308        LDMFD   r12,{r11,r12,r14}       @ r11= osamp
     309                                        @ r12= vol_l
     310                                        @ r14= vol_r
     311        LDMIA   r2,{r0,r1,r2,r8}        @ r0 = inPtr
     312                                        @ r1 = inLen
     313                                        @ r2 = opos
     314                                        @ r8 = opos_inc
     315        CMP     r11,#0                  @ if (osamp <= 0)
     316        BLE     SimpleRate_R_end        @   bale
     317        MOV     r10,#0
     318        MOV     r12,r12,LSL #8
     319        MOV     r14,r14,LSL #8
     320SimpleRate_R_loop:
     321        SUBS    r1, r1, #2      @ r1 = inLen -= 2
     322        BLT     SimpleRate_R_read
     323        SUBS    r2, r2, #1      @ r2 = opos--
     324        ADDGE   r0, r0, #4      @ if (r2 >= 0) { sr.inPtr += 2  and loop }
     325        BGE     SimpleRate_R_loop
     326SimpleRate_R_read_return:
     327        LDRSH   r5, [r0],#2     @ r5 = tmp0 = *inPtr++
     328        LDRSH   r4, [r0],#2     @ r4 = tmp1 = *inPtr++
     329        LDRSH   r6, [r3]        @ r6 = obuf[0]
     330        LDRSH   r7, [r3,#2]     @ r7 = obuf[1]
     331        ADD     r2, r2, r8      @ r2 = opos += opos_inc
     332        MUL     r4, r12,r4      @ r5 = tmp0*vol_l
     333        MUL     r5, r14,r5      @ r6 = tmp1*vol_r
     334
     335        ADDS    r6, r4, r6, LSL #16
     336        RSCVS   r6, r10,#1<<31
     337        ADDS    r7, r5, r7, LSL #16
     338        RSCVS   r7, r10,#1<<31
     339
     340        MOV     r6, r6, LSR #16
     341        MOV     r7, r7, LSR #16
     342
     343        STRH    r6, [r3],#2
     344        STRH    r7, [r3],#2
     345
     346        SUBS    r11,r11,#1
     347        BGT     SimpleRate_R_loop
     348SimpleRate_R_end:
     349        LDR     r14,[r13,#8]    @ r14 = sr
     350        ADD     r13,r13,#12
     351        STMIA   r14,{r0,r1,r2}
     352        LDMFD   r13!,{r4-r8,r10-r11,PC}
     353SimpleRate_R_read:
     354        LDR     r0, [r13,#4*2]  @ r0 = sr
     355        ADD     r0, r0, #16     @ r0 = inPtr = inBuf
     356        STMFD   r13!,{r0,r2-r3,r12,r14}
     357
     358        MOV     r1, r0          @ r1 = inBuf
     359        LDR     r0, [r13,#4*5]  @ r0 = AudioStream & input
     360        MOV     r2, #512        @ r2 = ARRAYSIZE(inBuf)
     361
     362        @ Calling back into C++ here. WinCE is fairly easy about such things
     363        @ but other OS are more awkward. r9 is preserved for Symbian, and
     364        @ we have 3+8+5 = 16 things on the stack (an even number).
     365        MOV     r14,PC
     366        LDR     PC,[r13,#4*6]   @ inLen = input.readBuffer(inBuf, 512)
     367        SUBS    r1, r0, #2      @ r1 = inLen-2
     368        LDMFD   r13!,{r0,r2-r3,r12,r14}
     369        BLT     SimpleRate_R_end
     370        SUBS    r2, r2, #1      @ r2 = opos--
     371        ADDGE   r0, r0, #4      @ if (r2 >= 0) { sr.inPtr += 2  and loop }
     372        BGE     SimpleRate_R_loop
     373        B       SimpleRate_R_read_return
     374
     375
     376ARM_LinearRate_M:
     377        @ r0 = AudioStream &input
     378        @ r1 = input.readBuffer
     379        @ r2 = input->sr
     380        @ r3 = obuf
     381        @ <> = osamp
     382        @ <> = vol_l
     383        @ <> = vol_r
     384        MOV     r12,r13
     385        STMFD   r13!,{r0-r1,r4-r11,r14}
     386        LDMFD   r12,{r11,r12,r14}       @ r11= osamp
     387                                        @ r12= vol_l
     388                                        @ r14= vol_r
     389        LDMIA   r2,{r0,r1,r8}           @ r0 = inPtr
     390                                        @ r1 = inLen
     391                                        @ r8 = opos
     392        CMP     r11,#0                  @ if (osamp <= 0)
     393        BLE     LinearRate_M_end        @   bale
     394        MOV     r12,r12,LSL #8
     395        MOV     r14,r14,LSL #8
     396        CMP     r1,#0
     397        BGT     LinearRate_M_part2
     398
     399        @ part1 - read input samples
     400LinearRate_M_loop:
     401        SUBS    r1, r1, #1      @ r1 = inLen -= 1
     402        BLT     LinearRate_M_read
     403LinearRate_M_read_return:
     404        LDR     r10,[r2, #16]   @ r10= icur[0,1]
     405        LDRSH   r5, [r0],#2     @ r5 = tmp1 = *inPtr++
     406        SUBS    r8, r8, #1      @ r8 = opos--
     407        STR     r10,[r2,#20]    @      ilast[0,1] = icur[0,1]
     408        STRH    r5, [r2,#16]    @      icur[0] = tmp1
     409        BGE     LinearRate_M_loop
     410
     411        @ part2 - form output samples
     412LinearRate_M_part2:
     413        @ We are guaranteed that opos < 0 here
     414        LDRSH   r6, [r2,#20]            @ r6 = ilast[0]
     415        LDRSH   r5, [r2,#16]            @ r5 = icur[0]
     416        LDRH    r4, [r2,#24]            @ r4 = opos_frac
     417        LDR     r10,[r2,#28]            @ r10= opos_frac_inc
     418        MOV     r6, r6, LSL #16         @ r6 = ilast[0]<<16
     419        SUB     r5, r5, r6, ASR #16     @ r5 = icur[0] - ilast[0]
     420        ADD     r6, r6, #1<<15          @ r6 = ilast[0]+1<<(FRAC_BITS-1)
     421        MLA     r6, r4, r5, r6  @ r6 = (icur[0]-ilast[0])*opos_frac+ilast[0]
     422
     423        ADD     r4, r4, r10             @ r4 = tmp = opos_frac+opos_inc_frac
     424        STRH    r4,[r2,#24]             @ opos_frac &= 65535
     425        ADD     r8, r8, r4, LSR #16     @ opos += (tmp>>FRAC_BITS)
     426
     427        LDRSH   r4, [r3]        @ r4 = obuf[0]
     428        LDRSH   r5, [r3,#2]     @ r5 = obuf[1]
     429        MOV     r6, r6, ASR #16
     430        MUL     r7, r12,r6      @ r7 = tmp0*vol_l
     431        MUL     r6, r14,r6      @ r6 = tmp1*vol_r
     432
     433        ADDS    r7, r7, r4, LSL #16
     434        MOV     r4, #0
     435        RSCVS   r7, r4, #1<<31
     436        ADDS    r6, r6, r5, LSL #16
     437        RSCVS   r6, r4, #1<<31
     438
     439        MOV     r7, r7, LSR #16
     440        MOV     r6, r6, LSR #16
     441
     442        LDR     r5, [r2,#12]    @ r5 = opos_inc
     443        STRH    r7, [r3],#2
     444        STRH    r6, [r3],#2
     445        SUBS    r11, r11,#1
     446        BLE     LinearRate_M_end
     447
     448        ADDS    r8, r8, r5      @ r8 = opos += opos_inc
     449        BLT     LinearRate_M_part2
     450        B       LinearRate_M_loop
     451LinearRate_M_end:
     452        ADD     r13,r13,#8
     453        STMIA   r2,{r0,r1,r8}
     454        LDMFD   r13!,{r4-r11,PC}
     455LinearRate_M_read:
     456        ADD     r0, r2, #32     @ r0 = inPtr = inBuf
     457        STMFD   r13!,{r0,r2-r3,r12,r14}
     458
     459        MOV     r1, r0          @ r1 = inBuf
     460        LDR     r0, [r13,#4*5]  @ r0 = AudioStream & input
     461        MOV     r2, #512        @ r2 = ARRAYSIZE(inBuf)
     462
     463        @ Calling back into C++ here. WinCE is fairly easy about such things
     464        @ but other OS are more awkward. r9 is preserved for Symbian, and
     465        @ we have 2+9+5 = 16 things on the stack (an even number).
     466        MOV     r14,PC
     467        LDR     PC,[r13,#4*6]   @ inLen = input.readBuffer(inBuf, 512)
     468        SUBS    r1, r0, #1      @ r1 = inLen-1
     469        LDMFD   r13!,{r0,r2-r3,r12,r14}
     470        BLT     LinearRate_M_end
     471        B       LinearRate_M_read_return
     472
     473ARM_LinearRate_S:
     474        @ r0 = AudioStream &input
     475        @ r1 = input.readBuffer
     476        @ r2 = input->sr
     477        @ r3 = obuf
     478        @ <> = osamp
     479        @ <> = vol_l
     480        @ <> = vol_r
     481        MOV     r12,r13
     482        STMFD   r13!,{r0-r1,r4-r11,r14}
     483        LDMFD   r12,{r11,r12,r14}       @ r11= osamp
     484                                        @ r12= vol_l
     485                                        @ r14= vol_r
     486        LDMIA   r2,{r0,r1,r8}           @ r0 = inPtr
     487                                        @ r1 = inLen
     488                                        @ r8 = opos
     489        CMP     r11,#0                  @ if (osamp <= 0)
     490        BLE     LinearRate_S_end        @   bale
     491        MOV     r12,r12,LSL #8
     492        MOV     r14,r14,LSL #8
     493        CMP     r1,#0
     494        BGT     LinearRate_S_part2
     495
     496        @ part1 - read input samples
     497LinearRate_S_loop:
     498        SUBS    r1, r1, #2      @ r1 = inLen -= 2
     499        BLT     LinearRate_S_read
     500LinearRate_S_read_return:
     501        LDR     r10,[r2, #16]   @ r10= icur[0,1]
     502        LDRSH   r5, [r0],#2     @ r5 = tmp0 = *inPtr++
     503        LDRSH   r6, [r0],#2     @ r5 = tmp1 = *inPtr++
     504        SUBS    r8, r8, #1      @ r8 = opos--
     505        STR     r10,[r2,#20]    @      ilast[0,1] = icur[0,1]
     506        STRH    r5, [r2,#16]    @      icur[0] = tmp0
     507        STRH    r6, [r2,#16]    @      icur[1] = tmp1
     508        BGE     LinearRate_S_loop
     509
     510        @ part2 - form output samples
     511LinearRate_S_part2:
     512        @ We are guaranteed that opos < 0 here
     513        LDRSH   r6, [r2,#20]            @ r6 = ilast[0]
     514        LDRSH   r5, [r2,#16]            @ r5 = icur[0]
     515        LDRH    r4, [r2,#24]            @ r4 = opos_frac
     516        MOV     r6, r6, LSL #16         @ r6 = ilast[0]<<16
     517        SUB     r5, r5, r6, ASR #16     @ r5 = icur[0] - ilast[0]
     518        ADD     r6, r6, #1<<15          @ r6 = ilast[0]+1<<(FRAC_BITS-1)
     519        MLA     r6, r4, r5, r6  @ r6 = (icur[0]-ilast[0])*opos_frac+ilast[0]
     520
     521        LDRSH   r7, [r2,#22]            @ r6 = ilast[1]
     522        LDRSH   r5, [r2,#18]            @ r5 = icur[1]
     523        LDR     r10,[r2,#28]            @ r10= opos_frac_inc
     524        MOV     r7, r7, LSL #16         @ r7 = ilast[1]<<16
     525        SUB     r5, r5, r7, ASR #16     @ r5 = icur[1] - ilast[1]
     526        ADD     r7, r7, #1<<15          @ r6 = ilast[1]+1<<(FRAC_BITS-1)
     527        MLA     r7, r4, r5, r7  @ r6 = (icur[1]-ilast[1])*opos_frac+ilast[1]
     528
     529        ADD     r4, r4, r10             @ r4 = tmp = opos_frac+opos_inc_frac
     530        STRH    r4,[r2,#24]             @ opos_frac &= 65535
     531        ADD     r8, r8, r4, LSR #16     @ opos += (tmp>>FRAC_BITS)
     532
     533        LDRSH   r4, [r3]        @ r4 = obuf[0]
     534        LDRSH   r5, [r3,#2]     @ r5 = obuf[1]
     535        MOV     r6, r6, ASR #16
     536        MOV     r7, r7, ASR #16
     537        MUL     r7, r12,r7      @ r7 = tmp0*vol_l
     538        MUL     r6, r14,r6      @ r6 = tmp1*vol_r
     539
     540        ADDS    r7, r7, r4, LSL #16
     541        MOV     r4, #0
     542        RSCVS   r7, r4, #1<<31
     543        ADDS    r6, r6, r5, LSL #16
     544        RSCVS   r6, r4, #1<<31
     545
     546        MOV     r7, r7, LSR #16
     547        MOV     r6, r6, LSR #16
     548
     549        LDR     r5, [r2,#12]    @ r5 = opos_inc
     550        STRH    r7, [r3],#2
     551        STRH    r6, [r3],#2
     552        SUBS    r11, r11,#1
     553        BLE     LinearRate_S_end
     554
     555        ADDS    r8, r8, r5      @ r8 = opos += opos_inc
     556        BLT     LinearRate_S_part2
     557        B       LinearRate_S_loop
     558LinearRate_S_end:
     559        ADD     r13,r13,#8
     560        STMIA   r2,{r0,r1,r8}
     561        LDMFD   r13!,{r4-r11,PC}
     562LinearRate_S_read:
     563        ADD     r0, r2, #32     @ r0 = inPtr = inBuf
     564        STMFD   r13!,{r0,r2-r3,r12,r14}
     565
     566        MOV     r1, r0          @ r1 = inBuf
     567        LDR     r0, [r13,#4*5]  @ r0 = AudioStream & input
     568        MOV     r2, #512        @ r2 = ARRAYSIZE(inBuf)
     569
     570        @ Calling back into C++ here. WinCE is fairly easy about such things
     571        @ but other OS are more awkward. r9 is preserved for Symbian, and
     572        @ we have 2+9+5 = 16 things on the stack (an even number).
     573        MOV     r14,PC
     574        LDR     PC,[r13,#4*6]   @ inLen = input.readBuffer(inBuf, 512)
     575        SUBS    r1, r0, #2      @ r1 = inLen-2
     576        LDMFD   r13!,{r0,r2-r3,r12,r14}
     577        BLT     LinearRate_S_end
     578        B       LinearRate_S_read_return
     579
     580ARM_LinearRate_R:
     581        @ r0 = AudioStream &input
     582        @ r1 = input.readBuffer
     583        @ r2 = input->sr
     584        @ r3 = obuf
     585        @ <> = osamp
     586        @ <> = vol_l
     587        @ <> = vol_r
     588        MOV     r12,r13
     589        STMFD   r13!,{r0-r1,r4-r11,r14}
     590        LDMFD   r12,{r11,r12,r14}       @ r11= osamp
     591                                        @ r12= vol_l
     592                                        @ r14= vol_r
     593        LDMIA   r2,{r0,r1,r8}           @ r0 = inPtr
     594                                        @ r1 = inLen
     595                                        @ r8 = opos
     596        CMP     r11,#0                  @ if (osamp <= 0)
     597        BLE     LinearRate_R_end        @   bale
     598        MOV     r12,r12,LSL #8
     599        MOV     r14,r14,LSL #8
     600        CMP     r1,#0
     601        BGT     LinearRate_R_part2
     602
     603        @ part1 - read input samples
     604LinearRate_R_loop:
     605        SUBS    r1, r1, #2      @ r1 = inLen -= 2
     606        BLT     LinearRate_R_read
     607LinearRate_R_read_return:
     608        LDR     r10,[r2, #16]   @ r10= icur[0,1]
     609        LDRSH   r5, [r0],#2     @ r5 = tmp0 = *inPtr++
     610        LDRSH   r6, [r0],#2     @ r5 = tmp1 = *inPtr++
     611        SUBS    r8, r8, #1      @ r8 = opos--
     612        STR     r10,[r2,#20]    @      ilast[0,1] = icur[0,1]
     613        STRH    r5, [r2,#16]    @      icur[0] = tmp0
     614        STRH    r6, [r2,#16]    @      icur[1] = tmp1
     615        BGE     LinearRate_R_loop
     616
     617        @ part2 - form output samples
     618LinearRate_R_part2:
     619        @ We are guaranteed that opos < 0 here
     620        LDRSH   r6, [r2,#20]            @ r6 = ilast[0]
     621        LDRSH   r5, [r2,#16]            @ r5 = icur[0]
     622        LDRH    r4, [r2,#24]            @ r4 = opos_frac
     623        MOV     r6, r6, LSL #16         @ r6 = ilast[0]<<16
     624        SUB     r5, r5, r6, ASR #16     @ r5 = icur[0] - ilast[0]
     625        ADD     r6, r6, #1<<15          @ r6 = ilast[0]+1<<(FRAC_BITS-1)
     626        MLA     r6, r4, r5, r6  @ r6 = (icur[0]-ilast[0])*opos_frac+ilast[0]
     627
     628        LDRSH   r7, [r2,#22]            @ r6 = ilast[1]
     629        LDRSH   r5, [r2,#18]            @ r5 = icur[1]
     630        LDR     r10,[r2,#28]            @ r10= opos_frac_inc
     631        MOV     r7, r7, LSL #16         @ r7 = ilast[1]<<16
     632        SUB     r5, r5, r7, ASR #16     @ r5 = icur[1] - ilast[1]
     633        ADD     r7, r7, #1<<15          @ r6 = ilast[1]+1<<(FRAC_BITS-1)
     634        MLA     r7, r4, r5, r7  @ r6 = (icur[1]-ilast[1])*opos_frac+ilast[1]
     635
     636        ADD     r4, r4, r10             @ r4 = tmp = opos_frac+opos_inc_frac
     637        STRH    r4,[r2,#24]             @ opos_frac &= 65535
     638        ADD     r8, r8, r4, LSR #16     @ opos += (tmp>>FRAC_BITS)
     639
     640        LDRSH   r4, [r3]        @ r4 = obuf[0]
     641        LDRSH   r5, [r3,#2]     @ r5 = obuf[1]
     642        MOV     r6, r6, ASR #16
     643        MOV     r7, r7, ASR #16
     644        MUL     r7, r12,r7      @ r7 = tmp0*vol_l
     645        MUL     r6, r14,r6      @ r6 = tmp1*vol_r
     646
     647        ADDS    r7, r7, r4, LSL #16
     648        MOV     r4, #0
     649        RSCVS   r7, r4, #1<<31
     650        ADDS    r6, r6, r5, LSL #16
     651        RSCVS   r6, r4, #1<<31
     652
     653        MOV     r7, r7, LSR #16
     654        MOV     r6, r6, LSR #16
     655
     656        LDR     r5, [r2,#12]    @ r5 = opos_inc
     657        STRH    r6, [r3],#2
     658        STRH    r7, [r3],#2
     659        SUBS    r11, r11,#1
     660        BLE     LinearRate_R_end
     661
     662        ADDS    r8, r8, r5      @ r8 = opos += opos_inc
     663        BLT     LinearRate_R_part2
     664        B       LinearRate_R_loop
     665LinearRate_R_end:
     666        ADD     r13,r13,#8
     667        STMIA   r2,{r0,r1,r8}
     668        LDMFD   r13!,{r4-r11,PC}
     669LinearRate_R_read:
     670        ADD     r0, r2, #32     @ r0 = inPtr = inBuf
     671        STMFD   r13!,{r0,r2-r3,r12,r14}
     672
     673        MOV     r1, r0          @ r1 = inBuf
     674        LDR     r0, [r13,#4*5]  @ r0 = AudioStream & input
     675        MOV     r2, #512        @ r2 = ARRAYSIZE(inBuf)
     676
     677        @ Calling back into C++ here. WinCE is fairly easy about such things
     678        @ but other OS are more awkward. r9 is preserved for Symbian, and
     679        @ we have 2+9+5 = 16 things on the stack (an even number).
     680        MOV     r14,PC
     681        LDR     PC,[r13,#4*6]   @ inLen = input.readBuffer(inBuf, 512)
     682        SUBS    r1, r0, #2      @ r1 = inLen-2
     683        LDMFD   r13!,{r0,r2-r3,r12,r14}
     684        BLT     LinearRate_R_end
     685        B       LinearRate_R_read_return
  • sound/module.mk

    Property changes on: sound/rate_arm_asm.s
    ___________________________________________________________________
    Name: svn:executable
       + *
    
     
    1616        mp3.o \
    1717        mpu401.o \
    1818        null.o \
    19         rate.o \
     19        rate_arm.o \
     20        rate_arm_asm.o \
    2021        voc.o \
    2122        vorbis.o \
    2223        wave.o \