**
** $VER: EncodeSamples_L2.asm 1.0 (27.8.2000)
**

        OPT P=68030/68882,ALINK,NOWARN

        INCLUDE "Exec/Types.i"
        INCLUDE "Exec.i"


    STRUCTURE   EncoderL2
        CPTR    enc_psAllocTable
        CPTR    enc_pdSB_Samples
        CPTR    enc_pdJ_Samples
        UBYTE   enc_bScalar,32*6
        UBYTE   enc_bJScale,32*3
    ENDSTRUCT   EncoderL2

    STRUCTURE   Encoder
        ULONG   enc_SBLimit
        ULONG   enc_JSBound
        ULONG   enc_NumChannels
        CPTR    BitBuffPtr
        UBYTE   enc_bBitAlloc,32*2
        DOUBLE  enc_adMultiples,64
    ENDSTRUCT   Encoder

    STRUCTURE   SBAlloc
        UWORD   wSteps
        UBYTE   bBits
        UBYTE   bGroup
        UWORD   wQuant
        UWORD   wStepMask
        ULONG   iTotalBits
        ULONG   iBitMask
    ENDSTRUCT   SBAlloc

        SBALLOC_MUL:    EQU     4       // SIZEOF_SBAlloc == 16

*----------------------------------------------------------------------------------------------------*


                SECTION "EncodeSamplesL2:0",CODE


                XDEF    _EncodeSamplesL2
                XREF    _quant_a__CoderL2C

    STRUCTURE   LocalDatas,LINK
        ULONG   maxch
        ULONG   frame
        ULONG   block
        ULONG   subband
        CPTR    AllocTable
        CPTR    pAlloc1
        UWORD   bands,3
    ENDSTRUCT   LocalDatas

;void CoderL2C::EncodeSamples(void *EncoderDatas, void *L2Datas)

_EncodeSamplesL2

                link    a5,#SIZEOF_LocalDatas
                PUSH    d2-d7/a2-a4/a6,EncodeSamples
                fmovem.x fp2/fp3,-(a7)

                move.l  $8(a5),a6               ; EncoderDatas
                move.l  12(a5),a4               ; L2Datas

        ; if (enc_JSBound != enc_SBLimit)
                move.l  enc_JSBound(a6),d2      ; JSBound
                move.l  enc_SBLimit(a6),d3      ; SBLimit
                cmp.l   d2,d3
                beq.s   EncodeSamples

        ;====== Recopier les informations J-STEREO (SubBandSamples et Scale)
        ;====== à la place des informations STEREO. De cette façon, la boucle
        ;====== d'encodage se trouve simplifiée.

                move.l  enc_pdJ_Samples(a4),a2  ; REAL *pJSamples = &*(enc_pdJ_Samples)[0][0][0];
                lea     enc_bJScale(a4),a1      ; UBYTE *pJScale  = &enc_bJScale[0][0];
                move.l  enc_pdSB_Samples(a4),a3 ; pSSamples = &(*enc_pdSB_Samples)[0][0][0][0];
                lea     enc_bScalar(a4),a0      ; pSScale = &enc_bScalar[0][0][0];

                moveq   #3-1,d4                 ; for (f = MAX_FRAMESETS; f > 0; --f)

.sb_loop        move.l  d2,d5                   ; for (i = enc_JSBound; i < enc_SBLimit; i++)

.scale_loop     moveq   #12-1,d7                ; for (j = SCALE_BLOCK, k = i; j > 0; k += SBLIMIT, --j)
                move.w  d5,d6

.copy_smpls     move.l  0(a2,d6.w*8),0(a3,d6.w*8)
                move.l  4(a2,d6.w*8),4(a3,d6.w*8)       ; pSSamples[k] = pJSamples[k];
                add.w   #32,d6
                dbra    d7,.copy_smpls

                move.b  0(a1,d5.l),0(a0,d5.l)   ; pSScale[i] = pJScale[i];
                addq.l  #1,d5
                cmp.l   d3,d5
                blo.b   .scale_loop

                add.w   #$1800,a3               ; pSSamples += SCALE_BLOCK * SBLIMIT * 2;
                add.w   #$C00,a2                ; pJSamples += SCALE_BLOCK * SBLIMIT;
                add.w   #$40,a0                 ; pSScale   += SBLIMIT * 2;
                add.w   #$20,a1                 ; pJScale   += SBLIMIT;
                dbra    d4,.sb_loop

;============== Seconde partie ================================================

EncodeSamples   ; a6 = Class Base
                move.l  BitBuffPtr(a6),a0       ; register UWORD *buffptr = BitBuffPtr;
                move.l  enc_pdSB_Samples(a4),a3 ; pSSamples = &(*enc_pdSB_Samples)[0][0][0][0];
                move.l  enc_psAllocTable(a4),AllocTable(a5)
                add.w   #enc_bScalar,a4         ; pSScale = &enc_bScalar[0][0][0];
                move.l  #3,frame(a5)            ; for (f = MAX_FRAMESETS; f > 0; --f) {

.frame_loop     clr.l   block(a5)               ; for (j = 0; j < SCALE_BLOCK * SBLIMIT; j += 3 * SBLIMIT) {

.scale_loop1    move.l  enc_NumChannels(a6),maxch(a5)   ; int maxch = enc_NumChannels;

                moveq   #0,d0                   ; for (i = 0; i < enc_SBLimit; i++) {

.sb_loop        move.l  d0,subband(a5)
                move.l  d0,d1
                asl.l   #8,d0
                add.l   AllocTable(a5),d0
                move.l  d0,pAlloc1(a5)          ; s_SBAlloc *pAlloc1 = &(*enc_psAllocTable)[i][0];

        ; if (i == enc_JSBound)
                cmp.l   enc_JSBound(a6),d1
                bne.b   .encode_stereo

                move.l  #1,maxch(a5)            ; maxch = 1;

.encode_stereo  moveq   #0,d6
                move.l  d1,d5                   ; z1 = i
                move.l  d5,d7                   ; for (k = 0, z1 = z2 = i; k < maxch; k++, z1 += SBLIMIT, z2 += SBLIMIT * SCALE_BLOCK) {

.k_loop
        ; if ( (n = pBitAlloc[z1]) )
                moveq   #0,d0
                move.b  enc_bBitAlloc(a6,d5.w),d0       ; n = pBitAlloc[z1]
                beq     .end_K_loop

                moveq   #0,d1
                move.b  0(a4,d5.w),d1           ; pScale[z1]
                asl.l   #SBALLOC_MUL,d0
                move.l  pAlloc1(a5),a1

                fmove.d enc_adMultiples(a6,d1.l*8),fp3 ; REAL multiple = enc_adMultiples[pSScale[z1]];
                lea     0(a1,d0.l),a2           ; s_SBAlloc *pAlloc = &pAlloc1[n];

                lea     _quant_a__CoderL2C,a1
                moveq   #0,d4
                move.w  wQuant(a2),d0
                move.w  wStepMask(a2),d4        ; ULONG stepmask = pAl
                fmove.d 0(a1,d0.w*8),fp2        ; REAL  quant = quant_a[pAlloc->wQuant]

        ; for (n = 0, z3 = z2 + j; n < 3; n++, z3 += SBLIMIT) {
                moveq   #0,d0
                move.l  d7,d2
                add.l   block(a5),d2            ; z3

.scale_loop2    fmove.d 0(a3,d2.w*8),fp0
                fmul.x  fp3,fp0
                fadd.s  #1.0,fp0                ; REAL d = pSSamples[z3] * multiple + 1.0;

                move.l  d4,d3                   ; sign = stepmask
                fmul.x  fp2,fp0
                fsub.s  #1.0,fp0                ; d = d * quant - 1.0;
                fboge   .computeSB              ; if (d < 0)

                moveq   #0,d3                   ; sign = 0;
                fadd.s  #1.0,fp0                ; d += 1.0;

.computeSB      fmove.l d4,fp1
                fmul.x  fp1,fp0
                fmove.l fp0,d1
                or.l    d3,d1
                move.w  d1,bands(a5,d0.w*2)     ; sbband[n] = ((ULONG) (d * stepmask)) | sign;
                addq.w  #1,d0
                add.w   #32,d2
                cmp.w   #3,d0
                blt.b   .scale_loop2

        ; if (pAlloc->bGroup)
                tst.b   bGroup(a2)
                beq.b   .mixSB

                moveq   #0,d0
                move.b  bBits(a2),d0             ; n = pAlloc->bBits;
                swap    d0
                move.w  bands(a5),d0
                move.l  d0,(a0)+
                move.w  bands+2(a5),d0
                move.l  d0,(a0)+
                move.w  bands+4(a5),d0
                move.l  d0,(a0)+
                bra.b   .end_K_loop

.mixSB          moveq   #0,d0
                move.w  wSteps(a2),d0           ; n = pAlloc->wSteps;
                move.w  bands+4(a5),d3
                mulu.w  d0,d3
                moveq   #0,d1
                move.w  bands+2(a5),d1
                add.l   d3,d1
                mulu.l  d1,d0
                moveq   #0,d1
                move.w  bands(a5),d1
                add.l   d0,d1                   ; x = sbband[0] + n * (sbband[1] + n * sbband[2]);
                moveq   #0,d0
                move.b  bBits(a2),d0
                move.w  d0,(a0)+                ; *buffptr++ = pAlloc->bBits;
                move.w  d1,(a0)+                ; *buffptr++ = x;

.end_K_loop     addq.l  #1,d6
                add.w   #32,d5
                add.w   #32*12,d7
                cmp.l   maxch(a5),d6
                blt     .k_loop

                move.l  subband(a5),d0
                addq.l  #1,d0
                cmp.l   enc_SBLimit(a6),d0
                blo     .sb_loop

                move.l  block(a5),d0
                add.l   #32*3,d0
                move.l  d0,block(a5)
                cmp.l   #32*12,d0
                blo     .scale_loop1

                add.w   #$1800,a3               ; pSSamples += SCALE_BLOCK * SBLIMIT * 2;
                add.w   #$40,a4                 ; pSScale   += SBLIMIT * 2;
                subq.l  #1,frame(a5)
                bgt     .frame_loop

                move.l  a0,BitBuffPtr(a6)       ; BitBuffPtr = buffptr;

                fmovem.x (a7)+,fp2/fp3
                POP     EncodeSamples
                unlk    a5
                rts


