Move playback channels to MidiMapping, fix tests

This commit is contained in:
Dmitri Ovodok 2019-02-11 12:37:56 +03:00
parent 568176a913
commit 830f989f71
14 changed files with 186 additions and 176 deletions

View file

@ -641,8 +641,8 @@ void Channel::write(XmlWriter& xml, const Part* part) const
if (_solo)
xml.tag("solo", _solo);
if (part && part->masterScore()->exportMidiMapping() && part->score() == part->masterScore()) {
xml.tag("midiPort", part->masterScore()->midiMapping(_channel)->port);
xml.tag("midiChannel", part->masterScore()->midiMapping(_channel)->channel);
xml.tag("midiPort", part->masterScore()->midiMapping(_channel)->port());
xml.tag("midiChannel", part->masterScore()->midiMapping(_channel)->channel());
}
for (const NamedEventList& a : midiActions)
a.write(xml, "MidiAction");
@ -728,20 +728,13 @@ void Channel::read(XmlReader& e, Part* part)
_solo = e.readInt();
else if (tag == "midiPort") {
int midiPort = e.readInt();
if (part) {
MidiMapping mm;
mm.port = midiPort;
mm.channel = -1;
mm.part = part;
mm.articulation = this;
part->masterScore()->midiMapping()->append(mm);
_channel = part->masterScore()->midiMapping()->size() - 1;
}
if (part && part->score()->isMaster())
part->masterScore()->addMidiMapping(this, part, midiPort, -1);
}
else if (tag == "midiChannel") {
int midiChannel = e.readInt();
if (part)
part->masterScore()->midiMapping(_channel)->channel = midiChannel;
if (part && part->score()->isMaster())
part->masterScore()->updateMidiMapping(this, part, -1, midiChannel);
}
else
e.unknown();

View file

@ -222,6 +222,7 @@ class PartChannelSettingsLink final : private ChannelListener {
void propertyChanged(Channel::Prop p) override;
public:
PartChannelSettingsLink() : _main(nullptr), _bound(nullptr), _excerpt(false) {}
PartChannelSettingsLink(Channel* main, Channel* bound, bool excerpt);
PartChannelSettingsLink(const PartChannelSettingsLink&) = delete;
PartChannelSettingsLink(PartChannelSettingsLink&&);

View file

@ -60,12 +60,12 @@ void MasterScore::checkMidiMapping()
int lastChannel = -1; // port*16+channel
int lastDrumPort = -1;
int index = 0;
for (MidiMapping m : _midiMapping) {
for (const MidiMapping& m : _midiMapping) {
if (index >= drum.size())
break;
if (drum[index]) {
lastDrumPort++;
if (m.port != lastDrumPort) {
if (m.port() != lastDrumPort) {
isSimpleMidiMaping = false;
return;
}
@ -76,7 +76,7 @@ void MasterScore::checkMidiMapping()
lastChannel++;
int p = lastChannel / 16;
int c = lastChannel % 16;
if (m.port != p || m.channel != c) {
if (m.port() != p || m.channel() != c) {
isSimpleMidiMaping = false;
return;
}
@ -163,27 +163,6 @@ void MasterScore::rebuildExcerptsMidiMapping()
}
}
//---------------------------------------------------------
// rebuildPlaybackChannels
//---------------------------------------------------------
void MasterScore::rebuildPlaybackChannels()
{
_playbackCommonSettingsLinks.clear();
_playbackChannels.clear();
for (const Part* part : parts()) {
for (const auto& i : *part->instruments()) {
const Instrument* instr = i.second;
for (Channel* channel : instr->channel()) {
Channel* playbackChannel = new Channel(*channel);
_playbackChannels.emplace_back(playbackChannel);
_playbackCommonSettingsLinks.emplace_back(playbackChannel, channel, /* excerpt */ false);
_midiMapping[playbackChannel->channel()].articulation = playbackChannel;
}
}
}
}
//---------------------------------------------------------
// reorderMidiMapping
// Set mappings in order you see in Add->Instruments
@ -191,19 +170,20 @@ void MasterScore::rebuildPlaybackChannels()
void MasterScore::reorderMidiMapping()
{
using std::swap;
int sequenceNumber = 0;
for (Part* part : parts()) {
const InstrumentList* il = part->instruments();
for (auto i = il->begin(); i != il->end(); ++i) {
const Instrument* instr = i->second;
for (Channel* channel : instr->channel()) {
if (!(_midiMapping[sequenceNumber].part == part
&& _midiMapping[sequenceNumber].articulation == channel)) {
if (!(_midiMapping[sequenceNumber].part() == part
&& _midiMapping[sequenceNumber].masterChannel == channel)) {
int shouldBe = channel->channel();
_midiMapping.swap(sequenceNumber, shouldBe);
_midiMapping[sequenceNumber].articulation->setChannel(sequenceNumber);
swap(_midiMapping[sequenceNumber], _midiMapping[shouldBe]);
_midiMapping[sequenceNumber].articulation()->setChannel(sequenceNumber);
channel->setChannel(sequenceNumber);
_midiMapping[shouldBe].articulation->setChannel(shouldBe);
_midiMapping[shouldBe].articulation()->setChannel(shouldBe);
}
sequenceNumber++;
}
@ -221,7 +201,7 @@ void MasterScore::removeDeletedMidiMapping()
int removeOffset = 0;
int mappingSize = _midiMapping.size();
for (int index = 0; index < mappingSize; index++) {
Part* p = midiMapping(index)->part;
Part* p = midiMapping(index)->part();
if (!parts().contains(p)) {
removeOffset++;
continue;
@ -231,9 +211,9 @@ void MasterScore::removeDeletedMidiMapping()
const InstrumentList* il = p->instruments();
for (auto i = il->begin(); i != il->end() && !channelExists; ++i) {
const Instrument* instr = i->second;
channelExists = (_midiMapping[index].articulation->channel() != -1
&& instr->channel().contains(_midiMapping[index].articulation)
&& !(_midiMapping[index].port == -1 && _midiMapping[index].channel == -1));
channelExists = (_midiMapping[index].articulation()->channel() != -1
&& instr->channel().contains(_midiMapping[index].masterChannel)
&& !(_midiMapping[index].port() == -1 && _midiMapping[index].channel() == -1));
if (channelExists)
break;
}
@ -243,15 +223,15 @@ void MasterScore::removeDeletedMidiMapping()
}
// Let's do a left shift by 'removeOffset' items if necessary
if (index != 0 && removeOffset != 0) {
_midiMapping[index-removeOffset] = _midiMapping[index];
_midiMapping[index-removeOffset] = std::move(_midiMapping[index]);
int chanVal = _midiMapping[index-removeOffset].articulation->channel();
_midiMapping[index-removeOffset].articulation->setChannel(chanVal - removeOffset);
const int chanVal = _midiMapping[index-removeOffset].articulation()->channel();
_midiMapping[index-removeOffset].articulation()->setChannel(chanVal - removeOffset);
}
}
// We have 'removeOffset' deleted instruments, let's remove their mappings
for (int index = 0; index < removeOffset; index++)
_midiMapping.removeLast();
_midiMapping.pop_back();
}
//---------------------------------------------------------
@ -266,12 +246,12 @@ int MasterScore::updateMidiMapping()
searchMidiMappingFrom = 0;
occupiedMidiChannels.reserve(_midiMapping.size()); // Bringing down the complexity of insertion to amortized O(1)
for(MidiMapping mm :_midiMapping) {
if (mm.port == -1 || mm.channel == -1)
for (const MidiMapping& mm :_midiMapping) {
if (mm.port() == -1 || mm.channel() == -1)
continue;
occupiedMidiChannels.insert((int)(mm.port)*16+(int)mm.channel);
if (maxport < mm.port)
maxport = mm.port;
occupiedMidiChannels.insert((int)(mm.port())*16+(int)mm.channel());
if (maxport < mm.port())
maxport = mm.port();
}
for (Part* part : parts()) {
@ -281,56 +261,100 @@ int MasterScore::updateMidiMapping()
bool drum = instr->useDrumset();
for (Channel* channel : instr->channel()) {
bool channelExists = false;
for (MidiMapping mapping: _midiMapping) {
if (channel == mapping.articulation && channel->channel() != -1) {
for (const MidiMapping& mapping: _midiMapping) {
if (channel == mapping.masterChannel && channel->channel() != -1) {
channelExists = true;
break;
}
}
// Channel could already exist, but have unassigned port or channel. Repair and continue
if (channelExists) {
if (_midiMapping[channel->channel()].port == -1) {
int nm = getNextFreeMidiMapping(-1, _midiMapping[channel->channel()].channel);
_midiMapping[channel->channel()].port = nm / 16;
if (_midiMapping[channel->channel()].port() == -1) {
const int nm = getNextFreeMidiMapping(-1, _midiMapping[channel->channel()].channel());
_midiMapping[channel->channel()]._port = nm / 16;
}
else if (_midiMapping[channel->channel()].channel == -1) {
else if (_midiMapping[channel->channel()].channel() == -1) {
if (drum) {
_midiMapping[channel->channel()].port = getNextFreeDrumMidiMapping() / 16;
_midiMapping[channel->channel()].channel = 9;
_midiMapping[channel->channel()]._port = getNextFreeDrumMidiMapping() / 16;
_midiMapping[channel->channel()]._channel = 9;
continue;
}
int nm = getNextFreeMidiMapping(_midiMapping[channel->channel()].port);
_midiMapping[channel->channel()].port = nm / 16;
_midiMapping[channel->channel()].channel = nm % 16;
int nm = getNextFreeMidiMapping(_midiMapping[channel->channel()].port());
_midiMapping[channel->channel()]._port = nm / 16;
_midiMapping[channel->channel()]._channel = nm % 16;
}
continue;
}
MidiMapping mm;
int midiPort;
int midiChannel;
if (drum) {
mm.port = getNextFreeDrumMidiMapping() / 16;
mm.channel = 9;
midiPort = getNextFreeDrumMidiMapping() / 16;
midiChannel = 9;
}
else {
int nm = getNextFreeMidiMapping();
mm.port = nm / 16;
mm.channel = nm % 16;
midiPort = nm / 16;
midiChannel = nm % 16;
}
if (mm.port > maxport)
maxport = mm.port;
if (midiPort > maxport)
maxport = midiPort;
mm.part = part;
// mm.articulation = channel; // now set in rebuildPlaybackChannels()
_midiMapping.append(mm);
channel->setChannel(_midiMapping.size() - 1);
addMidiMapping(channel, part, midiPort, midiChannel);
}
}
}
rebuildPlaybackChannels();
return maxport;
}
//---------------------------------------------------------
// addMidiMapping
//---------------------------------------------------------
void MasterScore::addMidiMapping(Channel* channel, Part* part, int midiPort, int midiChannel)
{
if (!part->score()->isMaster())
return;
MidiMapping mm;
mm._part = part;
mm.masterChannel = channel;
mm._articulation.reset(new Channel(*channel));
mm.link = PartChannelSettingsLink(mm.articulation(), mm.masterChannel, /* excerpt */ false);
mm._port = midiPort;
mm._channel = midiChannel;
const int mscoreChannel = _midiMapping.size();
mm._articulation->setChannel(mscoreChannel);
mm.masterChannel->setChannel(mscoreChannel);
_midiMapping.push_back(std::move(mm));
}
//---------------------------------------------------------
// updateMidiMapping
//---------------------------------------------------------
void MasterScore::updateMidiMapping(Channel* channel, Part* part, int midiPort, int midiChannel)
{
const int c = channel->channel();
if (c < 0)
return;
if (c >= int(masterScore()->midiMapping().size())) {
qDebug("Can't set midi channel: midiMapping is empty!");
return;
}
MidiMapping& mm = _midiMapping[c];
if (midiChannel != -1)
mm._channel = midiChannel;
if (midiPort != -1)
mm._port = midiPort;
if (part)
mm._part = part->masterPart();
}
} // namespace Ms

View file

@ -276,33 +276,10 @@ int Part::midiPort() const
void Part::setMidiChannel(int ch, int port, int tick)
{
Channel* channel = instrument(tick)->channel(0);
if (channel->channel() == -1) {
// Add new mapping
MidiMapping mm;
mm.part = this;
mm.articulation = channel;
mm.channel = -1;
mm.port = -1;
if (ch != -1)
mm.channel = ch;
if (port != -1)
mm.port = port;
channel->setChannel(masterScore()->midiMapping()->size());
masterScore()->midiMapping()->append(mm);
}
else {
// Update existing mapping
if (channel->channel() >= masterScore()->midiMapping()->size()) {
qDebug()<<"Can't' set midi channel: midiMapping is empty!";
return;
}
if (ch != -1)
masterScore()->midiMapping(channel->channel())->channel = ch;
if (port != -1)
masterScore()->midiMapping(channel->channel())->port = port;
masterScore()->midiMapping(channel->channel())->part = this;
}
if (channel->channel() == -1)
masterScore()->addMidiMapping(channel, this, port, ch);
else
masterScore()->updateMidiMapping(channel, this, port, ch);
}
//---------------------------------------------------------

View file

@ -3719,13 +3719,13 @@ ChordRest* Score::findCRinStaff(int tick, int staffIdx) const
void MasterScore::setSoloMute()
{
for (int i = 0; i < _midiMapping.size(); i++) {
Channel* b = _midiMapping[i].articulation;
for (unsigned i = 0; i < _midiMapping.size(); i++) {
Channel* b = _midiMapping[i].articulation();
if (b->solo()) {
b->setSoloMute(false);
for (int j = 0; j < _midiMapping.size(); j++) {
Channel* a = _midiMapping[j].articulation;
bool sameMidiMapping = _midiMapping[i].port == _midiMapping[j].port && _midiMapping[i].channel == _midiMapping[j].channel;
for (unsigned j = 0; j < _midiMapping.size(); j++) {
Channel* a = _midiMapping[j].articulation();
bool sameMidiMapping = _midiMapping[i].port() == _midiMapping[j].port() && _midiMapping[i].channel() == _midiMapping[j].channel();
a->setSoloMute((i != j && !a->solo() && !sameMidiMapping));
a->setSolo(i == j || a->solo() || sameMidiMapping);
}
@ -4458,8 +4458,8 @@ void MasterScore::setPlaybackScore(Score* score)
if (!_playbackScore)
return;
for (auto& ch : _playbackChannels)
ch->setSoloMute(true);
for (MidiMapping& mm : _midiMapping)
mm.articulation()->setSoloMute(true);
for (Part* part : score->parts()) {
for (auto& i : *part->instruments()) {
Instrument* instr = i.second;

View file

@ -160,11 +160,24 @@ class MeasureBaseList {
// MidiMapping
//---------------------------------------------------------
struct MidiMapping {
Part* part;
Channel* articulation;
signed char port;
signed char channel;
class MidiMapping {
Part* _part;
std::unique_ptr<Channel> _articulation;
signed char _port;
signed char _channel;
Channel* masterChannel;
PartChannelSettingsLink link;
MidiMapping() = default; // should be created only within MasterScore
friend class MasterScore;
public:
Part* part() { return _part; }
const Part* part() const { return _part; }
Channel* articulation() { return _articulation.get(); }
const Channel* articulation() const { return _articulation.get(); }
signed char port() const { return _port; }
signed char channel() const { return _channel; }
};
//---------------------------------------------------------
@ -1189,8 +1202,6 @@ class MasterScore : public Score {
TempoMap* _tempomap;
RepeatList* _repeatList;
QList<Excerpt*> _excerpts;
std::vector<std::unique_ptr<Channel>> _playbackChannels;
std::vector<PartChannelSettingsLink> _playbackCommonSettingsLinks;
std::vector<PartChannelSettingsLink> _playbackSettingsLinks;
Score* _playbackScore = nullptr;
Revisions* _revisions;
@ -1208,7 +1219,7 @@ class MasterScore : public Score {
int _midiPortCount { 0 }; // A count of JACK/ALSA midi out ports
QQueue<MidiInputEvent> _midiInputQueue; // MIDI events that have yet to be processed
std::list<MidiInputEvent> _activeMidiPitches; // MIDI keys currently being held down
QList<MidiMapping> _midiMapping;
std::vector<MidiMapping> _midiMapping;
bool isSimpleMidiMaping; // midi mapping is simple if all ports and channels
// don't decrease and don't have gaps
QSet<int> occupiedMidiChannels; // each entry is port*16+channel, port range: 0-inf, channel: 0-15
@ -1217,7 +1228,6 @@ class MasterScore : public Score {
void parseVersion(const QString&);
void reorderMidiMapping();
void rebuildExcerptsMidiMapping();
void rebuildPlaybackChannels();
void removeDeletedMidiMapping();
int updateMidiMapping();
@ -1289,10 +1299,12 @@ class MasterScore : public Score {
int midiPortCount() const { return _midiPortCount; }
void setMidiPortCount(int val) { _midiPortCount = val; }
QList<MidiMapping>* midiMapping() { return &_midiMapping; }
std::vector<MidiMapping>& midiMapping() { return _midiMapping; }
MidiMapping* midiMapping(int channel) { return &_midiMapping[channel]; }
int midiPort(int idx) const { return _midiMapping[idx].port; }
int midiChannel(int idx) const { return _midiMapping[idx].channel; }
void addMidiMapping(Channel* channel, Part* part, int midiPort, int midiChannel);
void updateMidiMapping(Channel* channel, Part* part, int midiPort, int midiChannel);
int midiPort(int idx) const { return _midiMapping[idx].port(); }
int midiChannel(int idx) const { return _midiMapping[idx].channel(); }
void rebuildMidiMapping();
void checkMidiMapping();
bool exportMidiMapping() { return !isSimpleMidiMaping; }
@ -1309,8 +1321,8 @@ class MasterScore : public Score {
void setPlaybackScore(Score*);
Score* playbackScore() { return _playbackScore; }
const Score* playbackScore() const { return _playbackScore; }
Channel* playbackChannel(const Channel* c) { return _midiMapping[c->channel()].articulation; }
const Channel* playbackChannel(const Channel* c) const { return _midiMapping[c->channel()].articulation; }
Channel* playbackChannel(const Channel* c) { return _midiMapping[c->channel()].articulation(); }
const Channel* playbackChannel(const Channel* c) const { return _midiMapping[c->channel()].articulation(); }
QFileInfo* fileInfo() { return &info; }
const QFileInfo* fileInfo() const { return &info; }

View file

@ -102,7 +102,7 @@ bool MuseScore::saveAudio(Score* score, QIODevice *device, std::function<bool(fl
if (e.type() == ME_INVALID)
continue;
e.setChannel(a->channel());
int syntiIdx = synth->index(score->masterScore()->midiMapping(a->channel())->articulation->synti());
int syntiIdx = synth->index(score->masterScore()->midiMapping(a->channel())->articulation()->synti());
synth->play(e, syntiIdx);
}
}
@ -137,7 +137,7 @@ bool MuseScore::saveAudio(Score* score, QIODevice *device, std::function<bool(fl
const NPlayEvent& e = playPos->second;
if (e.isChannelEvent()) {
int channelIdx = e.channel();
Channel* c = score->masterScore()->midiMapping(channelIdx)->articulation;
const Channel* c = score->masterScore()->midiMapping(channelIdx)->articulation();
if (!c->mute()) {
synth->play(e, synth->index(c->synti()));
}

View file

@ -5014,7 +5014,7 @@ static void partList(XmlWriter& xml, Score* score, const QList<Part*>& il, MxmlI
int instNr = ii.key();
int midiPort = part->midiPort() + 1;
if (ii.value()->channel().size() > 0)
midiPort = score->masterScore()->midiMapping(ii.value()->channel(0)->channel())->port + 1;
midiPort = score->masterScore()->midiMapping(ii.value()->channel(0)->channel())->port() + 1;
if (midiPort >= 1 && midiPort <= 16)
xml.tag(QString("midi-device %1 port=\"%2\"").arg(instrId(idx+1, instNr + 1)).arg(midiPort), "");
else

View file

@ -210,8 +210,8 @@ void Mixer::on_partOnlyCheckBox_toggled(bool checked)
setPlaybackScore(_activeScore->masterScore()->playbackScore());
// Prevent muted channels from sounding
for (const MidiMapping& mm : *_activeScore->masterScore()->midiMapping()) {
const Channel* ch = mm.articulation;
for (const MidiMapping& mm : _activeScore->masterScore()->midiMapping()) {
const Channel* ch = mm.articulation();
if (ch && (ch->mute() || ch->soloMute()))
seq->stopNotes(ch->channel());
}

View file

@ -161,7 +161,7 @@ void MixerDetails::updateFromTrack()
Channel* chan = _mti->focusedChan();
//Check if drumkit
bool drum = midiMap->part->instrument()->useDrumset();
const bool drum = midiMap->part()->instrument()->useDrumset();
drumkitCheck->blockSignals(true);
drumkitCheck->setChecked(drum);
drumkitCheck->blockSignals(false);
@ -235,8 +235,8 @@ void MixerDetails::updateFromTrack()
chorusSlider->setValue((int)chan->chorus());
chorusSpinBox->setValue(chan->chorus());
portSpinBox->setValue(part->masterScore()->midiMapping(chan->channel())->port + 1);
channelSpinBox->setValue(part->masterScore()->midiMapping(chan->channel())->channel + 1);
portSpinBox->setValue(part->masterScore()->midiMapping(chan->channel())->port() + 1);
channelSpinBox->setValue(part->masterScore()->midiMapping(chan->channel())->channel() + 1);
trackColorLabel->blockSignals(false);
volumeSlider->blockSignals(false);
@ -351,7 +351,7 @@ void MixerDetails::propertyChanged(Channel::Prop property)
return;
MidiMapping* _midiMap = _mti->midiMap();
Channel* chan = _midiMap->articulation;
Channel* chan = _midiMap->articulation();
switch (property) {
case Channel::Prop::VOLUME: {
@ -480,8 +480,8 @@ void MixerDetails::patchChanged(int n)
return;
}
Part* part = _mti->midiMap()->part;
Channel* channel = _mti->midiMap()->articulation;
Part* part = _mti->midiMap()->part();
Channel* channel = _mti->midiMap()->articulation();
Score* score = part->score();
if (score) {
score->startCmd();
@ -552,8 +552,7 @@ void MixerDetails::midiChannelChanged(int)
int c = channelSpinBox->value() - 1;
MidiMapping* midiMap = _mti->midiMap();
midiMap->port = p;
midiMap->channel = c;
part->masterScore()->updateMidiMapping(midiMap->articulation(), part, p, c);
// channel->updateInitList();
part->score()->setInstrumentsChanged(true);

View file

@ -6686,7 +6686,7 @@ bool MuseScore::saveMp3(Score* score, QIODevice* device, bool& wasCanceled)
if (e.type() == ME_INVALID)
continue;
e.setChannel(a->channel());
int syntiIdx= synth->index(score->masterScore()->midiMapping(a->channel())->articulation->synti());
int syntiIdx= synth->index(score->masterScore()->midiMapping(a->channel())->articulation()->synti());
synth->play(e, syntiIdx);
}
}
@ -6736,7 +6736,7 @@ bool MuseScore::saveMp3(Score* score, QIODevice* device, bool& wasCanceled)
const NPlayEvent& e = playPos->second;
if (e.isChannelEvent()) {
int channelIdx = e.channel();
Channel* c = score->masterScore()->midiMapping(channelIdx)->articulation;
Channel* c = score->masterScore()->midiMapping(channelIdx)->articulation();
if (!c->mute()) {
synth->play(e, synth->index(c->synti()));
}

View file

@ -290,10 +290,10 @@ void MuseScore::oscVolChannel(double val)
PathObject* po = (PathObject*) sender();
int i = po->path().mid(4).toInt() - 1;
QList<MidiMapping>* mms = cs->masterScore()->midiMapping();
if( i >= 0 && i < mms->size()) {
MidiMapping mm = mms->at(i);
Channel* channel = mm.articulation;
auto& mms = cs->masterScore()->midiMapping();
if( i >= 0 && i < int(mms.size())) {
MidiMapping& mm = mms[i];
Channel* channel = mm.articulation();
int iv = lrint(val*127);
seq->setController(channel->channel(), CTRL_VOLUME, iv);
channel->setVolume(val * 100.0);
@ -313,10 +313,10 @@ void MuseScore::oscPanChannel(double val)
PathObject* po = (PathObject*) sender();
int i = po->path().mid(4).toInt() - 1;
QList<MidiMapping>* mms = cs->masterScore()->midiMapping();
if (i >= 0 && i < mms->size()) {
MidiMapping mm = mms->at(i);
Channel* channel = mm.articulation;
auto& mms = cs->masterScore()->midiMapping();
if (i >= 0 && i < int(mms.size())) {
MidiMapping& mm = mms[i];
Channel* channel = mm.articulation();
int iv = lrint((val + 1) * 64);
seq->setController(channel->channel(), CTRL_PANPOT, iv);
channel->setPan(val * 180.0);
@ -336,10 +336,10 @@ void MuseScore::oscMuteChannel(double val)
PathObject* po = (PathObject*) sender();
int i = po->path().mid(5).toInt() - 1;
QList<MidiMapping>* mms = cs->masterScore()->midiMapping();
if (i >= 0 && i < mms->size()) {
MidiMapping mm = mms->at(i);
Channel* channel = mm.articulation;
auto& mms = cs->masterScore()->midiMapping();
if (i >= 0 && i < int(mms.size())) {
MidiMapping& mm = mms[i];
Channel* channel = mm.articulation();
channel->setMute(val==0.0f ? false : true);
if (mixer)
mixer->getPartAtIndex(i)->mute->setChecked(channel->mute());

View file

@ -113,8 +113,8 @@ void PartEdit::setPart(Part* p, Channel* a)
}
}
_setChecked(drumset, p->instrument()->useDrumset());
_setValue(portSpinBox, part->masterScore()->midiMapping(a->channel())->port + 1);
_setValue(channelSpinBox, part->masterScore()->midiMapping(a->channel())->channel + 1);
_setValue(portSpinBox, part->masterScore()->midiMapping(a->channel())->port() + 1);
_setValue(channelSpinBox, part->masterScore()->midiMapping(a->channel())->channel() + 1);
QHBoxLayout* hb = voiceButtonBox;
int idx = 0;
@ -431,7 +431,7 @@ void PartEdit::midiChannelChanged(int)
int c = channelSpinBox->value() - 1;
// 1 is for going up, -1 for going down
int direction = copysign(1, c - part->masterScore()->midiMapping(channel->channel())->channel);
int direction = copysign(1, c - part->masterScore()->midiMapping(channel->channel())->channel());
// Channel 9 is special for drums
if (part->instrument()->useDrumset() && c != 9) {
@ -487,8 +487,8 @@ void PartEdit::midiChannelChanged(int)
QPushButton *assignFreeChannel = msgBox.addButton(tr("Assign next free MIDI channel"), QMessageBox::HelpRole);
msgBox.setDefaultButton(QMessageBox::Ok);
if (msgBox.exec() == QMessageBox::Cancel) {
_setValue(channelSpinBox, part->masterScore()->midiMapping(channel->channel())->channel + 1);
_setValue(portSpinBox, part->masterScore()->midiMapping(channel->channel())->port + 1);
_setValue(channelSpinBox, part->masterScore()->midiMapping(channel->channel())->channel() + 1);
_setValue(portSpinBox, part->masterScore()->midiMapping(channel->channel())->port() + 1);
needSync = false;
break;
}
@ -498,10 +498,12 @@ void PartEdit::midiChannelChanged(int)
break;
}
// Sync
_setValue(channelSpinBox, newChannel % 16 + 1);
_setValue(portSpinBox, newChannel / 16 + 1);
part->masterScore()->midiMapping(channel->channel())->channel = newChannel % 16;
part->masterScore()->midiMapping(channel->channel())->port = newChannel / 16;
const int port = newChannel / 16;
const int channelNo = newChannel % 16;
_setValue(channelSpinBox, channelNo + 1);
_setValue(portSpinBox, port + 1);
MasterScore* ms = part->masterScore();
ms->updateMidiMapping(ms->playbackChannel(channel), part, port, channelNo);
channel->setVolume(lrint(pe->volume->value()));
channel->setPan(lrint(pe->pan->value()));
channel->setReverb(lrint(pe->reverb->value()));
@ -525,12 +527,14 @@ void PartEdit::midiChannelChanged(int)
}
channel->updateInitList();
if (needSync) {
_setValue(channelSpinBox, newChannel % 16 + 1);
_setValue(portSpinBox, newChannel / 16 + 1);
part->masterScore()->midiMapping(channel->channel())->channel = newChannel % 16;
part->masterScore()->midiMapping(channel->channel())->port = newChannel / 16;
part->score()->setInstrumentsChanged(true);
part->score()->setLayoutAll();
const int port = newChannel / 16;
const int channelNo = newChannel % 16;
_setValue(channelSpinBox, channelNo + 1);
_setValue(portSpinBox, port + 1);
MasterScore* ms = part->masterScore();
ms->updateMidiMapping(ms->playbackChannel(channel), part, port, channelNo);
ms->setInstrumentsChanged(true);
ms->setLayoutAll();
seq->initInstruments();
}
else {

View file

@ -966,8 +966,8 @@ void Seq::initInstruments(bool realTime)
_driver->updateOutPortCount(maxMidiOutPort + 1);
}
foreach(const MidiMapping& mm, *cs->midiMapping()) {
Channel* channel = mm.articulation;
for (const MidiMapping& mm : cs->midiMapping()) {
const Channel* channel = mm.articulation();
for (const MidiCoreEvent& e : channel->init) {
if (e.type() == ME_INVALID)
continue;
@ -978,7 +978,7 @@ void Seq::initInstruments(bool realTime)
sendEvent(event);
}
// Setting pitch bend sensitivity to 12 semitones for external synthesizers
if ((preferences.getBool(PREF_IO_JACK_USEJACKMIDI) || preferences.getBool(PREF_IO_ALSA_USEALSAAUDIO)) && mm.channel != 9) {
if ((preferences.getBool(PREF_IO_JACK_USEJACKMIDI) || preferences.getBool(PREF_IO_ALSA_USEALSAAUDIO)) && mm.channel() != 9) {
if (realTime) {
putEvent(NPlayEvent(ME_CONTROLLER, channel->channel(), CTRL_LRPN, 0));
putEvent(NPlayEvent(ME_CONTROLLER, channel->channel(), CTRL_HRPN, 0));
@ -1202,7 +1202,7 @@ void Seq::stopNotes(int channel, bool realTime)
};
// Stop notes in all channels
if (channel == -1) {
for(int ch = 0; ch < cs->midiMapping()->size(); ch++) {
for(int ch = 0; ch < int(cs->midiMapping().size()); ch++) {
send(NPlayEvent(ME_CONTROLLER, ch, CTRL_SUSTAIN, 0));
send(NPlayEvent(ME_CONTROLLER, ch, CTRL_ALL_NOTES_OFF, 0));
if (cs->midiChannel(ch) != 9)
@ -1421,13 +1421,13 @@ void Seq::putEvent(const NPlayEvent& event, unsigned framePos)
if (!cs)
return;
int channel = event.channel();
if (channel >= cs->midiMapping()->size()) {
qDebug("bad channel value %d >= %d", channel, cs->midiMapping()->size());
if (channel >= int(cs->midiMapping().size())) {
qDebug("bad channel value %d >= %d", channel, int(cs->midiMapping().size()));
return;
}
// audio
int syntiIdx= _synti->index(cs->midiMapping(channel)->articulation->synti());
int syntiIdx= _synti->index(cs->midiMapping(channel)->articulation()->synti());
_synti->play(event, syntiIdx);
// midi