voiceman.cc

00001 /**************************************************************************
00002 
00003     voiceman.cc - The VoiceManager class handles a set of voices for synths
00004     This file is part of LibKMid 0.9.5
00005     Copyright (C) 1997,98,99,2000  Antonio Larrosa Jimenez
00006     LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html
00007 
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Library General Public
00010     License as published by the Free Software Foundation; either
00011     version 2 of the License, or (at your option) any later version.
00012  
00013     This library is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     Library General Public License for more details.
00017  
00018     You should have received a copy of the GNU Library General Public License
00019     along with this library; see the file COPYING.LIB.  If not, write to
00020     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021     Boston, MA 02110-1301, USA.
00022 
00023     Send comments and bug fixes to Antonio Larrosa <larrosa@kde.org>
00024 
00025 ***************************************************************************/
00026 
00027 #include "voiceman.h"
00028 #include <stdio.h>
00029 #ifdef HAVE_CONFIG_H
00030 #include <config.h>
00031 #endif
00032 
00033 VoiceManager::VoiceManager(int totalvoices)
00034 {
00035   nvoices=totalvoices;
00036 
00037   FirstVoice=new voice;
00038   FirstVoice->id=0;
00039   FirstVoice->channel=0;
00040   FirstVoice->note=0;
00041   FirstVoice->used=0;
00042   FirstVoice->prev=NULL;
00043 
00044   voice *ptrb=FirstVoice;
00045   voice *ptr=NULL;
00046   int i;
00047   for (i=1;i<nvoices;i++)
00048   {
00049     ptr=new voice;
00050     ptrb->next=ptr;
00051     ptr->id=i;
00052     ptr->channel=0;
00053     ptr->note=0;
00054     ptr->used=0;
00055     ptr->prev=ptrb;    
00056     ptrb=ptr;
00057   }
00058   LastVoice=ptr;
00059   LastVoice->next=NULL;
00060   LastnotusedVoice=LastVoice;
00061 
00062   VoiceList=new voice *[nvoices];
00063   ptr=FirstVoice;
00064   for (i=0;i<nvoices;i++)
00065   {
00066     VoiceList[i]=ptr;
00067     ptr=ptr->next; 
00068   }
00069   searcher_aid=new voice;
00070 }
00071 
00072 VoiceManager::~VoiceManager()
00073 {
00074   voice *ptr=FirstVoice;
00075   voice *ptr2;
00076   while (ptr!=NULL)
00077   {
00078     ptr2=ptr->next;
00079     delete ptr;
00080     ptr=ptr2;
00081   }
00082   FirstVoice=NULL;
00083   LastVoice=NULL;
00084   LastnotusedVoice=NULL;
00085 
00086   delete [] VoiceList;
00087   VoiceList=NULL;
00088 
00089   delete searcher_aid;
00090 }
00091 
00092 void VoiceManager::clearLists(void)
00093 {
00094 #ifdef VOICEMANDEBUG
00095   printf("voicemanager::cleanLists\n");
00096 #endif
00097   voice *ptr=FirstVoice;
00098   voice *ptr2=FirstVoice;
00099   while (ptr!=NULL)
00100   {
00101     ptr->used=0;
00102     ptr2=ptr;
00103     ptr=ptr->next;
00104   }
00105   LastVoice=ptr2;
00106   LastnotusedVoice=ptr2;
00107 
00108 }
00109 
00110 int VoiceManager::allocateVoice(int chn,int key)
00111 {
00112   // First, we take the allocated voice out of the first place of the list
00113   if ((LastnotusedVoice!=NULL)&&(LastnotusedVoice->id==FirstVoice->id))
00114   {
00115 #ifdef VOICEMANDEBUG
00116     printf("Used last voice !\n");
00117 #endif
00118     LastnotusedVoice=NULL;
00119   }
00120   voice *newvoice=FirstVoice;
00121   FirstVoice=FirstVoice->next;
00122   FirstVoice->prev=NULL;
00123 
00124 #ifdef VOICEMANDEBUG
00125   printf("Allocating id :%d\n",newvoice->id);
00126 #endif
00127   // then we put the allocated voice at the end of the list
00128   LastVoice->next=newvoice;
00129   newvoice->prev=LastVoice;
00130   LastVoice=newvoice;
00131   LastVoice->next=NULL;
00132 
00133   newvoice->channel=chn;
00134   newvoice->note=key;
00135 
00136 #ifdef VOICEMANDEBUG
00137   if (newvoice->used==1) 
00138   {
00139     printf("Replacing voice : %d\n",newvoice->id);
00140   }
00141 #endif
00142   newvoice->used=1;
00143 
00144   //dispStat();
00145   return newvoice->id;
00146 }
00147 
00148 void VoiceManager::deallocateVoice(int id)
00149 {
00150   voice *delvoice=VoiceList[id];
00151 #ifdef VOICEMANDEBUG
00152   printf("Deallocating id :%d\n",id);
00153 #endif
00154   if (delvoice->id==LastVoice->id)
00155   {
00156     LastVoice=delvoice->prev;
00157     LastVoice->next=NULL;
00158 
00159     if (LastnotusedVoice==NULL)
00160     {
00161       delvoice->next=FirstVoice;
00162       FirstVoice->prev=delvoice;
00163       FirstVoice=delvoice;
00164       FirstVoice->prev=NULL;
00165       LastnotusedVoice=FirstVoice;
00166     }
00167     else
00168     {
00169       if (LastnotusedVoice->next==NULL)
00170       {
00171     LastnotusedVoice->next=delvoice;
00172     delvoice->prev=LastnotusedVoice;
00173     delvoice->next=NULL;
00174     LastnotusedVoice=delvoice;
00175     LastVoice=delvoice;
00176       }
00177       else
00178       {
00179     delvoice->next=LastnotusedVoice->next;
00180     delvoice->next->prev=delvoice;
00181     delvoice->prev=LastnotusedVoice;
00182     LastnotusedVoice->next=delvoice;
00183     LastnotusedVoice=delvoice;
00184       }
00185     }
00186   }
00187   else
00188   {
00189     if (delvoice->prev!=NULL)
00190     {
00191       delvoice->prev->next=delvoice->next;
00192       delvoice->next->prev=delvoice->prev;
00193       if (LastnotusedVoice==NULL)
00194       {
00195     delvoice->next=FirstVoice;
00196     FirstVoice->prev=delvoice;
00197     FirstVoice=delvoice;
00198     FirstVoice->prev=NULL;
00199     LastnotusedVoice=FirstVoice;                                                    }
00200       else
00201       {
00202     if (LastnotusedVoice->next==NULL)
00203     {
00204       LastnotusedVoice->next=delvoice;
00205       delvoice->prev=LastnotusedVoice;
00206       delvoice->next=NULL;
00207       LastnotusedVoice=delvoice;
00208       LastVoice=delvoice;
00209     }
00210     else
00211     {
00212       delvoice->next=LastnotusedVoice->next;
00213       delvoice->next->prev=delvoice;
00214       delvoice->prev=LastnotusedVoice;
00215       LastnotusedVoice->next=delvoice;
00216       LastnotusedVoice=delvoice;
00217     }
00218       }
00219     }
00220   }
00221   delvoice->used=0;
00222 
00223   //  dispStat();
00224 }
00225 
00226 void VoiceManager::initSearch(void)
00227 {
00228   searcher=searcher_aid;
00229   searcher_aid->prev=LastVoice;
00230 }
00231 
00232 int VoiceManager::search(int chn)
00233 {
00234   if (searcher==NULL) return -1;
00235   searcher=searcher->prev;
00236 
00237   while (searcher!=NULL)
00238   {
00239     if (searcher->used==0) return -1;
00240     if (searcher->channel==chn) 
00241     {   
00242       return searcher->id;
00243     }
00244     searcher=searcher->prev;
00245   }
00246   return -1;
00247 }
00248 
00249 int VoiceManager::search(int chn,int note)
00250 {
00251   if (searcher==NULL) return -1;
00252   searcher=searcher->prev;
00253   while ((searcher!=NULL))
00254   {
00255     if (searcher->used==0) return -1;
00256     if ((searcher->channel==chn)&&(searcher->note==note)) 
00257     {
00258       return searcher->id;
00259     }
00260     searcher=searcher->prev;
00261   }
00262   return -1;
00263 }
00264 
00265 /*
00266 void VoiceManager::dispStat(void)
00267 {
00268 #ifdef VOICEMANDEBUG
00269   printf("Stats\n");
00270   voice *ptr=FirstVoice;
00271   while (ptr!=NULL)
00272   {
00273     printf("Voice %d is %s\n",ptr->id,(ptr->used==0)?("off"):("on"));
00274     ptr=ptr->next;
00275   }
00276   if (LastnotusedVoice!=NULL) printf("LnuV = %d\n",LastnotusedVoice->id);
00277 #endif
00278 }
00279 */
KDE Home | KDE Accessibility Home | Description of Access Keys