package com.xenoage.zong.io.midi.out.channels;
import com.xenoage.zong.commands.core.music.PartAdd;
import com.xenoage.zong.core.Score;
import com.xenoage.zong.core.instrument.Instrument;
import com.xenoage.zong.core.instrument.PitchedInstrument;
import com.xenoage.zong.core.instrument.UnpitchedInstrument;
import com.xenoage.zong.core.music.Part;
import lombok.val;
import org.junit.Test;
import static com.xenoage.utils.collections.CollectionUtils.alist;
import static com.xenoage.utils.kernel.Range.range;
import static com.xenoage.zong.io.midi.out.MidiConverter.channel10;
import static com.xenoage.zong.io.midi.out.channels.ChannelMap.unused;
import static org.junit.Assert.*;
/**
* Tests for {@link ChannelMapper}.
*
* @author Andreas Wenger
*/
public class ChannelMapperTest {
private static final int drums = 0;
/**
* Enough channels: each part gets its own channel.
*/
@Test public void testFewParts() {
int[] midiPrograms = { 20, 21, 22, drums, 20, 20};
int[] partStavesCount = { 2, 2, 1, 1, 1, 3};
int[] expectedChannels = {0, 0, 1, 1, 2, channel10, 3, 4, 4, 4};
val score = createScore(midiPrograms, partStavesCount);
assertEquals(new ChannelMap(expectedChannels), ChannelMapper.createChannelMap(score));
}
/**
* More parts than channels: reuse channels for parts with the same MIDI program.
*/
@Test public void testManyParts() {
int c10 = channel10;
int[] midiPrograms = { 20, 21, 22, drums, 20, 20, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, drums, 5};
int[] partStavesCount = { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2};
int[] expectedChannels = {0, 0, 1, 1, 2, c10, 0, 0, 3, 4, 5, 6, 7, 8, 10, 3, 4, 5, c10, c10, 7, 7};
val score = createScore(midiPrograms, partStavesCount);
assertEquals(new ChannelMap(expectedChannels), ChannelMapper.createChannelMap(score));
}
/**
* Too many parts: last parts are not used.
*/
@Test public void testTooManyParts() {
int c10 = channel10;
int un = unused;
int[] midiPrograms = {1, 2, 3, 4, 5, 6, 7, 8, 9, drums, 10, 11, 12, 13, 14, 15, 16, 17, drums, 18, 15, 10, 5, 1};
int[] partStavesCount = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
int[] expectedChannels = {0, 1, 2, 3, 4, 5, 6, 7, 8, c10, 10, 11, 12, 13, 14, 15, un, un, c10, un, 15, 10, 4, 0};
val score = createScore(midiPrograms, partStavesCount);
assertEquals(new ChannelMap(expectedChannels), ChannelMapper.createChannelMap(score));
}
private Score createScore(int[] midiPrograms, int... partStavesCount) {
val score = new Score();
for (int iPart : range(partStavesCount)) {
Instrument instrument;
if (midiPrograms[iPart] == drums)
instrument = new UnpitchedInstrument("part " + iPart);
else
instrument = new PitchedInstrument("part " + iPart, midiPrograms[iPart]);
new PartAdd(score, new Part("", null,
partStavesCount[iPart], alist(instrument)), iPart, null).execute();
}
return score;
}
}