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/libtdemid.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 */