diff options
Diffstat (limited to 'libtdemid/voiceman.cpp')
-rw-r--r-- | libtdemid/voiceman.cpp | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/libtdemid/voiceman.cpp b/libtdemid/voiceman.cpp new file mode 100644 index 000000000..fddf68f0e --- /dev/null +++ b/libtdemid/voiceman.cpp @@ -0,0 +1,279 @@ +/************************************************************************** + + voiceman.cpp - The VoiceManager class handles a set of voices for synths + This file is part of LibKMid 0.9.5 + Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez + LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libtdemid.html + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + Send comments and bug fixes to Antonio Larrosa <larrosa@kde.org> + +***************************************************************************/ + +#include "voiceman.h" +#include <stdio.h> +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +VoiceManager::VoiceManager(int totalvoices) +{ + nvoices=totalvoices; + + FirstVoice=new voice; + FirstVoice->id=0; + FirstVoice->channel=0; + FirstVoice->note=0; + FirstVoice->used=0; + FirstVoice->prev=NULL; + + voice *ptrb=FirstVoice; + voice *ptr=NULL; + int i; + for (i=1;i<nvoices;i++) + { + ptr=new voice; + ptrb->next=ptr; + ptr->id=i; + ptr->channel=0; + ptr->note=0; + ptr->used=0; + ptr->prev=ptrb; + ptrb=ptr; + } + LastVoice=ptr; + LastVoice->next=NULL; + LastnotusedVoice=LastVoice; + + VoiceList=new voice *[nvoices]; + ptr=FirstVoice; + for (i=0;i<nvoices;i++) + { + VoiceList[i]=ptr; + ptr=ptr->next; + } + searcher_aid=new voice; +} + +VoiceManager::~VoiceManager() +{ + voice *ptr=FirstVoice; + voice *ptr2; + while (ptr!=NULL) + { + ptr2=ptr->next; + delete ptr; + ptr=ptr2; + } + FirstVoice=NULL; + LastVoice=NULL; + LastnotusedVoice=NULL; + + delete [] VoiceList; + VoiceList=NULL; + + delete searcher_aid; +} + +void VoiceManager::clearLists(void) +{ +#ifdef VOICEMANDEBUG + printf("voicemanager::cleanLists\n"); +#endif + voice *ptr=FirstVoice; + voice *ptr2=FirstVoice; + while (ptr!=NULL) + { + ptr->used=0; + ptr2=ptr; + ptr=ptr->next; + } + LastVoice=ptr2; + LastnotusedVoice=ptr2; + +} + +int VoiceManager::allocateVoice(int chn,int key) +{ + // First, we take the allocated voice out of the first place of the list + if ((LastnotusedVoice!=NULL)&&(LastnotusedVoice->id==FirstVoice->id)) + { +#ifdef VOICEMANDEBUG + printf("Used last voice !\n"); +#endif + LastnotusedVoice=NULL; + } + voice *newvoice=FirstVoice; + FirstVoice=FirstVoice->next; + FirstVoice->prev=NULL; + +#ifdef VOICEMANDEBUG + printf("Allocating id :%d\n",newvoice->id); +#endif + // then we put the allocated voice at the end of the list + LastVoice->next=newvoice; + newvoice->prev=LastVoice; + LastVoice=newvoice; + LastVoice->next=NULL; + + newvoice->channel=chn; + newvoice->note=key; + +#ifdef VOICEMANDEBUG + if (newvoice->used==1) + { + printf("Replacing voice : %d\n",newvoice->id); + } +#endif + newvoice->used=1; + + //dispStat(); + return newvoice->id; +} + +void VoiceManager::deallocateVoice(int id) +{ + voice *delvoice=VoiceList[id]; +#ifdef VOICEMANDEBUG + printf("Deallocating id :%d\n",id); +#endif + if (delvoice->id==LastVoice->id) + { + LastVoice=delvoice->prev; + LastVoice->next=NULL; + + if (LastnotusedVoice==NULL) + { + delvoice->next=FirstVoice; + FirstVoice->prev=delvoice; + FirstVoice=delvoice; + FirstVoice->prev=NULL; + LastnotusedVoice=FirstVoice; + } + else + { + if (LastnotusedVoice->next==NULL) + { + LastnotusedVoice->next=delvoice; + delvoice->prev=LastnotusedVoice; + delvoice->next=NULL; + LastnotusedVoice=delvoice; + LastVoice=delvoice; + } + else + { + delvoice->next=LastnotusedVoice->next; + delvoice->next->prev=delvoice; + delvoice->prev=LastnotusedVoice; + LastnotusedVoice->next=delvoice; + LastnotusedVoice=delvoice; + } + } + } + else + { + if (delvoice->prev!=NULL) + { + delvoice->prev->next=delvoice->next; + delvoice->next->prev=delvoice->prev; + if (LastnotusedVoice==NULL) + { + delvoice->next=FirstVoice; + FirstVoice->prev=delvoice; + FirstVoice=delvoice; + FirstVoice->prev=NULL; + LastnotusedVoice=FirstVoice; } + else + { + if (LastnotusedVoice->next==NULL) + { + LastnotusedVoice->next=delvoice; + delvoice->prev=LastnotusedVoice; + delvoice->next=NULL; + LastnotusedVoice=delvoice; + LastVoice=delvoice; + } + else + { + delvoice->next=LastnotusedVoice->next; + delvoice->next->prev=delvoice; + delvoice->prev=LastnotusedVoice; + LastnotusedVoice->next=delvoice; + LastnotusedVoice=delvoice; + } + } + } + } + delvoice->used=0; + + // dispStat(); +} + +void VoiceManager::initSearch(void) +{ + searcher=searcher_aid; + searcher_aid->prev=LastVoice; +} + +int VoiceManager::search(int chn) +{ + if (searcher==NULL) return -1; + searcher=searcher->prev; + + while (searcher!=NULL) + { + if (searcher->used==0) return -1; + if (searcher->channel==chn) + { + return searcher->id; + } + searcher=searcher->prev; + } + return -1; +} + +int VoiceManager::search(int chn,int note) +{ + if (searcher==NULL) return -1; + searcher=searcher->prev; + while ((searcher!=NULL)) + { + if (searcher->used==0) return -1; + if ((searcher->channel==chn)&&(searcher->note==note)) + { + return searcher->id; + } + searcher=searcher->prev; + } + return -1; +} + +/* +void VoiceManager::dispStat(void) +{ +#ifdef VOICEMANDEBUG + printf("Stats\n"); + voice *ptr=FirstVoice; + while (ptr!=NULL) + { + printf("Voice %d is %s\n",ptr->id,(ptr->used==0)?("off"):("on")); + ptr=ptr->next; + } + if (LastnotusedVoice!=NULL) printf("LnuV = %d\n",LastnotusedVoice->id); +#endif +} +*/ |