bank.c++ 4.41 KB
//====================================================================
// bank.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 <stdlib.h>
#include "libbank.h"

#define MAX_PROGRAMS    128

class Program {
  public:
    ICInst      *i;
    int         number; /* program number */
};

ICBank::ICBank()
{
    declclass = ICBANK;
    size = sizeof(ALBank) - sizeof(ALInstrument *); /* size in file */
    
    percussion  = 0;
    maxPrograms = -1;
    sampleRate  = 44100;
    bank        = 0;
}

ICInst* ICBank::GetPercussion(void)
{
    return percussion;
}

void ICBank::AddProgram(ICInst *i, int number)
{
    FailIf(!i, IC_PARAMETER_ERR);
    FailIf(i->GetObjectClass() != ICINST, IC_TYPE_ERR);
    
    Program *p = new Program;
    FailIf(!p, IC_INTERNAL_ERR);

    p->i      = i;
    p->number = number;
    
    progList.Append(p);

    maxPrograms = MAX(maxPrograms, number);
    size = sizeof(ALBank) + (maxPrograms+1)*sizeof(ALBank *);
}

void ICBank::SetPercussionDefault(ICInst *i)
{
    FailIf(!i, IC_PARAMETER_ERR);
    FailIf(i->GetObjectClass() != ICINST, IC_TYPE_ERR);    
    
    percussion = i;
    
}

void ICBank::SetSampleRate(int rate) 
{
    sampleRate = rate;
}

void ICBank::ThinPrograms(void)
{
    Node        *node = progList.head;
    Node        *prev = (Node *)&progList.head;
    Program     *p;
    ICInst      *i;

    if(!percussion->GetUsedFlag())
        percussion = 0;
    
    while ( node != 0)
    {
        p= (Program *)node->data;
        i = p->i;

        if(i->GetUsedFlag())
        {
            prev = node;
            node = node->next;
        }
        else
        {
            node = progList.Remove(node,prev);
        }
    }
}
        
void ICBank::Assemble()
{
    Node        *obj;

    size = Size();    

    ALBank *b = (ALBank *)calloc(1, size);
    FailIf(!b, IC_INTERNAL_ERR);

    b->sampleRate = sampleRate;
    if (maxPrograms != -1) {
        b->instCount = maxPrograms + 1;
    } else {
        b->instCount = 0;
    }

    if (percussion)
        b->percussion = (ALInstrument *)percussion->GetObjectOffset();
    
    for (obj = progList.head; obj != 0; obj = obj->next) {
        Program *p= (Program *)obj->data;
        ICInst  *i = p->i;
        b->instArray[p->number] = (ALInstrument *)i->GetObjectOffset();
    }
    
    bank  = b;
    thing = bank;

}

void ICBank::Prune()
{
    Node *node;

    this->IncRefCount();

    if (percussion)
        percussion->Prune();
    
    for (node = progList.head; node != 0; node = node->next) {
        Program *p= (Program *)node->data;
        ICInst  *i = p->i;
        i->Prune();
    }
}

void ICBank::Print()
{
    int  i;
    
    if (declid)
        printf("Bank: %s\n", declid->name);
    else 
        printf("Bank: \n");

    ICObject::Print();
    
    printf("\tinstCount:\t= %d\n", bank->instCount);
    
    for (i = 0; i < bank->instCount; i++) {
        printf("\tprogram[%d] = \t%x\n", i, bank->instArray[i]);
    }

    printf("\n");
}

void ICBank::MarkUsed(char program, char key)
{
    Node        *obj;
    
    if(!usedFlag)
        usedFlag = TRUE;
    
    if(program == 128)
        percussion->MarkUsed(key);

    else
    {
        for (obj = progList.head; obj != 0; obj = obj->next)
        {
            Program *p= (Program *)obj->data;
            ICInst  *i = p->i;
            if(p->number == program)
            {
                i->MarkUsed(key);
                    return;
            }
        }
        fprintf(stderr,"Note on not matched to instrument, program %d, key %d\n",program,key);
    }
}

#ifdef OLD_STUFF
void ICBank::ResetChanMap(void)
{
    int     i;

    for(i=0;i<16;i++)
        ChanProgMap[i] = 0;

    if(percussion)
        percActive = TRUE;
}
#endif