package org.herac.tuxguitar.gm; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class GMChannelRouter { public static final short MAX_CHANNELS = 16; public static final short PERCUSSION_CHANNEL = 9; private List midiChannels; public GMChannelRouter(){ this.midiChannels = new ArrayList(); } public void resetRoutes(){ this.midiChannels.clear(); } public void removeRoute(GMChannelRoute route){ if( this.midiChannels.contains(route) ){ this.midiChannels.remove(route); } } public GMChannelRoute getRoute(int channelId){ Iterator channelIt = this.midiChannels.iterator(); while( channelIt.hasNext() ){ GMChannelRoute midiChannel = (GMChannelRoute) channelIt.next(); if( midiChannel.getChannelId() == channelId ){ return midiChannel; } } return null; } public void configureRoutes(GMChannelRoute route, boolean percussionChannel){ List conflictingRoutes = null; if( this.midiChannels.contains(route) ){ this.midiChannels.remove(route); } // Allways channel 9 for percussions if( percussionChannel ){ route.setChannel1(PERCUSSION_CHANNEL); route.setChannel2(PERCUSSION_CHANNEL); } else { // Use custom routes if( route.getChannel1() >= 0 ){ if( route.getChannel2() < 0 ){ route.setChannel2( route.getChannel1() ); } conflictingRoutes = findConflictingRoutes(route); } // Add default routes else { List freeChannels = getFreeChannels(); route.setChannel1(( freeChannels.size() > 0 ? ((Integer)freeChannels.get(0)).intValue() : GMChannelRoute.NULL_VALUE ) ); route.setChannel2(( freeChannels.size() > 1 ? ((Integer)freeChannels.get(1)).intValue() : route.getChannel1() ) ); } } this.midiChannels.add( route ); // Reconfigure conflicting routes if( conflictingRoutes != null ){ Iterator it = conflictingRoutes.iterator(); while( it.hasNext() ){ GMChannelRoute conflictingRoute = (GMChannelRoute)it.next(); conflictingRoute.setChannel1(GMChannelRoute.NULL_VALUE); conflictingRoute.setChannel2(GMChannelRoute.NULL_VALUE); configureRoutes(conflictingRoute, false); } } } public List findConflictingRoutes(GMChannelRoute gmChannelRoute){ List routes = new ArrayList(); Iterator it = this.midiChannels.iterator(); while( it.hasNext() ){ GMChannelRoute route = (GMChannelRoute) it.next(); if(!route.equals(gmChannelRoute) ){ if( route.getChannel1() == gmChannelRoute.getChannel1() || route.getChannel1() == gmChannelRoute.getChannel2() || route.getChannel2() == gmChannelRoute.getChannel1() || route.getChannel2() == gmChannelRoute.getChannel2() ){ routes.add( route ); } } } return routes; } public List getFreeChannels(){ return getFreeChannels(null); } public List getFreeChannels(GMChannelRoute forRoute){ List freeChannels = new ArrayList(); for( int ch = 0 ; ch < MAX_CHANNELS ; ch ++ ){ if( ch != PERCUSSION_CHANNEL ){ boolean isFreeChannel = true; Iterator channelIt = this.midiChannels.iterator(); while( channelIt.hasNext() ){ GMChannelRoute route = (GMChannelRoute) channelIt.next(); if( forRoute == null || !forRoute.equals( route ) ){ if( route.getChannel1() == ch || route.getChannel2() == ch){ isFreeChannel = false; } } } if( isFreeChannel ){ freeChannels.add(new Integer(ch)); } } } return freeChannels; } }