use of com.xenoage.zong.core.music.Part in project Zong by Xenoage.
the class ChannelMapper method createChannelForEachPart.
/**
* Each pitched part gets its own channel.
* All unpitched parts get channel 10.
*/
private static int[] createChannelForEachPart(Score score) {
int[] staffChannels = new int[score.getStavesCount()];
int iChannel = 0;
for (Part part : score.getStavesList().getParts()) {
boolean isPitched = isPitched(part);
int channel = (isPitched ? iChannel : channel10);
for (int iStaff : score.getStavesList().getPartStaffIndices(part).getRange()) staffChannels[iStaff] = channel;
// after pitched part: increment channel number
if (isPitched)
// don't use channel 10
iChannel = iChannel + 1 + (iChannel + 1 == channel10 ? 1 : 0);
}
return staffChannels;
}
use of com.xenoage.zong.core.music.Part in project Zong by Xenoage.
the class ChannelMapper method createReusedChannels.
/**
* Share channel for parts with the same instrument (MIDI program).
* If none is left, the part is ignored (channel index = {@link ChannelMap#unused}).
* All unpitched parts get channel 10.
*/
private static int[] createReusedChannels(Score score) {
int[] staffChannels = new int[score.getStavesCount()];
int nextFreeChannel = 0;
HashMap<Integer, Integer> programToDeviceMap = map();
for (Part part : score.getStavesList().getParts()) {
boolean isPitched = isPitched(part);
// find channel
int channel;
if (isPitched) {
// pitched part: create new channel or reuse existing channel
val pitchedInstr = (PitchedInstrument) part.getFirstInstrument();
int program = pitchedInstr.getMidiProgram();
channel = notNull(programToDeviceMap.get(program), nextFreeChannel);
if (channel >= maxChannelsCount) {
// no more channel left for this part
channel = unused;
} else if (channel == nextFreeChannel) {
// new channel created: increment next channel number and remember program
// don't use channel 10
nextFreeChannel = nextFreeChannel + 1 + (nextFreeChannel + 1 == channel10 ? 1 : 0);
programToDeviceMap.put(program, channel);
}
} else {
// unpitched part: always use channel 10
channel = channel10;
}
// apply channel to all staves
for (int iStaff : score.getStavesList().getPartStaffIndices(part).getRange()) {
staffChannels[iStaff] = channel;
}
}
return staffChannels;
}
use of com.xenoage.zong.core.music.Part in project Zong by Xenoage.
the class ChannelMapper method createChannelMap.
public static ChannelMap createChannelMap(Score score) {
int[] staffChannels;
// get number of parts which have not channel 10
int melodicPartsCount = 0;
for (Part part : score.getStavesList().getParts()) {
if (isPitched(part)) {
melodicPartsCount++;
}
}
// find out if there are enough channels for all parts
if (melodicPartsCount < maxChannelsCount)
// each part gets its own channel
staffChannels = createChannelForEachPart(score);
else
// try to reuse channels
staffChannels = createReusedChannels(score);
return new ChannelMap(staffChannels);
}
use of com.xenoage.zong.core.music.Part in project Zong by Xenoage.
the class InfoDialog method setScore.
public void setScore(Score score) {
ScoreInfo info = score.getInfo();
lblTitle.setText(info.getTitle());
txtWorkNumber.setText(info.getWorkNumber());
txtWorkTitle.setText(info.getWorkTitle());
txtMovementNumber.setText(info.getMovementNumber());
txtMovementTitle.setText(info.getMovementTitle());
// creators
String s = "-";
if (info.getCreators().size() > 0) {
s = "";
for (Creator creator : info.getCreators()) s += (creator.getType() != null ? creator.getType() + ": " : "") + creator.getName() + "\n";
}
txtCreators.setText(s);
// rights
s = "-";
if (info.getRights().size() > 0) {
s = "";
for (Rights rights : info.getRights()) s += (rights.getType() != null ? rights.getType() + ": " : "") + rights.getText() + "\n";
}
txtRights.setText(s);
// parts
s = "-";
if (score.getStavesList().getParts().size() > 0) {
s = "";
for (int i : range(score.getStavesList().getParts())) {
Part part = score.getStavesList().getParts().get(i);
s += i + ": " + part.getName() + "\n";
}
}
txtParts.setText(s);
}
use of com.xenoage.zong.core.music.Part in project Zong by Xenoage.
the class ChannelMapperTest method createScore.
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;
}
Aggregations