save.c 3.85 KB
/*====================================================================
 * save.c
 *
 * Copyright 1993, Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics,
 * Inc.; the contents of this file may not be disclosed to third
 * parties, copied or duplicated in any form, in whole or in part,
 * without the prior written permission of Silicon Graphics, Inc.
 *
 * RESTRICTED RIGHTS LEGEND:
 * Use, duplication or disclosure by the Government is subject to
 * restrictions as set forth in subdivision (c)(1)(ii) of the Rights
 * in Technical Data and Computer Software clause at DFARS
 * 252.227-7013, and/or in similar or successor clauses in the FAR,
 * DOD or NASA FAR Supplement. Unpublished - rights reserved under the
 * Copyright Laws of the United States.
 *====================================================================*/

#include <libaudio.h>
#include "synthInternals.h"
#include <em.h>
#include <os.h>

void alSaveNew(ALSave *f) 
{
    int  i;
    
    /*
     * init filter superclass
     */

    alFilterNew((ALFilter *) f, alSavePull, alSaveParam, AL_SAVE);
    
    /*
     * init the save state, which is a virtual dram address
     */
    
    f->dramout = 0;
    f->first = 1;
    f->ratio = 1.0;
    f->delta  = 0.0;
    
}

Acmd *alSavePull(void *filter, short *outp, int outCount, int flags, Acmd *p) 

{
    Acmd        *ptr = p;
    ALSave *f = (ALSave *)filter;
    ALFilter    *source;
    int         inCount;
    int         incr;
    float       fCount;

    /*
     * determine how many samples to generate - should be a multiple of 8
     */
    fCount = f->delta + (f->ratio * (float) outCount);
    inCount = (int) fCount;
    if (inCount & 0x7)
        inCount += 8 - (inCount & 0x7);
    f->delta = fCount - (float)inCount;
    
    if (source = f->filter.source) {
        ptr = (*source->handler)(source, outp, inCount, flags, ptr);
    } else {
        /* error */
    }
    
    if (f->ratio < 1.0){

        incr = (int)(f->ratio * UNITY_PITCH);
        
        /*
         * Left channel
         */
        aSetBuffer(ptr++, 0, AL_MAIN_L_OUT, 0, outCount<<1);
        if (f->first){
            aResample(ptr++, A_INIT, incr, osVirtualToPhysical(f->stateL.rstate));
        } else
            aResample(ptr++, A_OUT, incr, osVirtualToPhysical(f->stateL.rstate));
        
        /*
         * Right channel
         */
        aSetBuffer(ptr++, 0, AL_MAIN_R_OUT, outCount<<1, outCount<<1);
        if (f->first){
            f->first = 0;
            aResample(ptr++, A_INIT, incr, osVirtualToPhysical(f->stateR.rstate));
        } else
            aResample(ptr++, A_OUT, incr, osVirtualToPhysical(f->stateR.rstate));
        aSetBuffer(ptr++, 0, 0, outCount<<2, outCount<<1);
        aInterleave(ptr++, 0, outCount<<1);
        aSetBuffer(ptr++, 0, 0, outCount<<2, outCount<<2);
        aSaveBuffer(ptr++, f->dramout);
    } else {
        aSetBuffer(ptr++, 0, 0, 0, outCount<<1);
        aInterleave(ptr++, AL_MAIN_L_OUT, AL_MAIN_R_OUT);
        aSetBuffer(ptr++, 0, 0, 0, outCount<<2);
        aSaveBuffer(ptr++, f->dramout);
    }
    
    return ptr;
}

int alSaveParam(void *filter, int paramID, void *param)
{
    ALSave *a = (ALSave *) filter;
    ALFilter *f = (ALFilter *) filter;
    int pp = (int) param;
    union {
        float           f;
        int             i;
    } data;

    switch (paramID) {
        case (AL_FILTER_SET_SOURCE):
            f->source = (ALFilter *) param;
            break;

        case (AL_FILTER_SET_DRAM): 
            a->dramout = pp;
            break;
            
        case (AL_FILTER_SET_PITCH):
            a->delta = 0.0;
            data.i = (int) param;
            a->ratio = data.f;
            break;
        
        default:
            if (f->source)
              (*f->source->setParam)(f, paramID, param);
            break;
    }
    return 0;
            
}