On 2011-09-27 11:16, Christian Schoenebeck wrote:
On Tuesday 27 September 2011 00:26:29 Christopher Cherrett wrote:
Hey guys,
We have a feature that sends all patch or program changes in a song to
linuxsampler at one time.
The reason for our patch was to couple the bank and the program changes
so that they did not get disconnected.
What was happening was LS was loosing what bank belonged to what patch
and we were no able to load successfully everything we wanted.
Our patch couples the two and solves the issue.
Andreas, I remember you had something on your mind about this patch a while
ago. Can you now remember what it was? Or was it another patch that
Christopher mentioned in the past?
It was this patch, but I don't quite remember what my thoughts were.
Maybe it was just that I never looked deeply enough on the patch to
understand it correctly. I'll try again now:
First, the patch is a bit badly formatted (tabs instead of white spaces,
trailing white spaces, old code commented instead of removed, "added by"
comments). I've cleaned it up and attach the new version.
There are really two different changes in the patch. First the move of
GetMidiBankLsb/GetMidiBankMsb calls from the disk thread back to the
calling thread. I like that change. Maybe as Christian already said, it
would have been more readable to add separate parameters for bank msb
and lsb instead of merging them into a uint32, but I can live with it.
The other change is kind of similar. The call to PrepareLoadInstrument
is moved from the calling thread to the InstrumentManagerThread. I think
I understand this change too, and agree that it is a good one. But after
this change maybe we should remove the PrepareLoadInstrument method and
instead let LoadInstrument take the filename and index as parameters?
As the first change removes the call to SetMidiProgram, GetMidiProgram
will not return the correct value anymore. That doesn't matter
currently, as GetMidiProgram is never called. Should we remove those two
functions to avoid future confusion?
/Andreas
Index: src/engines/EngineChannel.cpp
===================================================================
--- src/engines/EngineChannel.cpp (revision 2276)
+++ src/engines/EngineChannel.cpp (arbetskopia)
@@ -300,12 +300,15 @@
}
}
- void EngineChannel::ExecuteProgramChange(uint8_t Program) {
- dmsg(1,("Received MIDI program change (prog=%d)\n",Program));
+ void EngineChannel::ExecuteProgramChange(uint32_t Program) {
+ uint8_t hb = (Program >> 16) & 0xff;
+ uint8_t lb = (Program >> 8) & 0xff;
+ uint8_t pc = Program & 0x7f;
+
+ dmsg(1,("Received MIDI program change (msb=%d) (lsb=%d) (prog=%d)\n",
hb ,lb, pc));
std::vector<int> maps = MidiInstrumentMapper::Maps();
if (maps.empty()) return;
- SetMidiProgram(Program);
if (UsesNoMidiInstrumentMap()) return;
if (MidiInstrumentMapper::GetMapCount() == 0) return;
// retrieve the MIDI instrument map this engine channel is assigned to
@@ -313,9 +316,9 @@
? MidiInstrumentMapper::GetDefaultMap() /*default*/ :
GetMidiInstrumentMap();
// is there an entry for this MIDI bank&prog pair in that map?
midi_prog_index_t midiIndex;
- midiIndex.midi_bank_msb = GetMidiBankMsb();
- midiIndex.midi_bank_lsb = GetMidiBankLsb();
- midiIndex.midi_prog = GetMidiProgram();
+ midiIndex.midi_bank_msb = hb;
+ midiIndex.midi_bank_lsb = lb;
+ midiIndex.midi_prog = pc;
optional<MidiInstrumentMapper::entry_t> mapping =
MidiInstrumentMapper::GetEntry(iMapID, midiIndex);
if (mapping) { // if mapping exists ...
Index: src/engines/InstrumentManagerThread.h
===================================================================
--- src/engines/InstrumentManagerThread.h (revision 2276)
+++ src/engines/InstrumentManagerThread.h (arbetskopia)
@@ -61,6 +61,8 @@
InstrumentManager* pManager; ///< only for
INSTR_MODE commands
InstrumentManager::instrument_id_t instrumentId; ///< only for
INSTR_MODE commands
InstrumentManager::mode_t mode; ///< only for
INSTR_MODE commands
+ String InstrumentFile;
+ int InstrumentIdx;
};
// Instance variables.
Index: src/engines/EngineChannel.h
===================================================================
--- src/engines/EngineChannel.h (revision 2276)
+++ src/engines/EngineChannel.h (arbetskopia)
@@ -346,7 +346,7 @@
*
* This method is not real-time safe.
*/
- void ExecuteProgramChange(uint8_t Program);
+ void ExecuteProgramChange(uint32_t Program);
protected:
EngineChannel();
Index: src/engines/common/DiskThreadBase.h
===================================================================
--- src/engines/common/DiskThreadBase.h (revision 2276)
+++ src/engines/common/DiskThreadBase.h (arbetskopia)
@@ -67,7 +67,7 @@
bool bNotify;
};
struct program_change_command_t {
- uint8_t Program;
+ uint32_t Program;
EngineChannel* pEngineChannel;
};
// Attributes
@@ -382,7 +382,7 @@
* Tell the disk thread to do a program change on the specified
* EngineChannel.
*/
- int OrderProgramChange(uint8_t Program, EngineChannel*
pEngineChannel) {
+ int OrderProgramChange(uint32_t Program, EngineChannel*
pEngineChannel) {
program_change_command_t cmd;
cmd.Program = Program;
cmd.pEngineChannel = pEngineChannel;
Index: src/engines/sf2/EngineChannel.cpp
===================================================================
--- src/engines/sf2/EngineChannel.cpp (revision 2276)
+++ src/engines/sf2/EngineChannel.cpp (arbetskopia)
@@ -64,7 +64,8 @@
if(engine == NULL) return;
if(engine->GetDiskThread()) {
- engine->GetDiskThread()->OrderProgramChange(Program, this);
+ uint32_t merged = (GetMidiBankMsb() << 16) | (GetMidiBankLsb() <<
8) | Program;
+ engine->GetDiskThread()->OrderProgramChange(merged, this);
} else {
// TODO:
}
Index: src/engines/sfz/EngineChannel.cpp
===================================================================
--- src/engines/sfz/EngineChannel.cpp (revision 2276)
+++ src/engines/sfz/EngineChannel.cpp (arbetskopia)
@@ -66,7 +66,8 @@
if(engine == NULL) return;
if(engine->GetDiskThread()) {
- engine->GetDiskThread()->OrderProgramChange(Program, this);
+ uint32_t merged = (GetMidiBankMsb() << 16) | (GetMidiBankLsb() <<
8) | Program;
+ engine->GetDiskThread()->OrderProgramChange(merged, this);
} else {
// TODO:
}
Index: src/engines/gig/EngineChannel.cpp
===================================================================
--- src/engines/gig/EngineChannel.cpp (revision 2276)
+++ src/engines/gig/EngineChannel.cpp (arbetskopia)
@@ -62,7 +62,8 @@
if(engine == NULL) return;
if(engine->GetDiskThread()) {
- engine->GetDiskThread()->OrderProgramChange(Program, this);
+ uint32_t merged = (GetMidiBankMsb() << 16) | (GetMidiBankLsb() <<
8) | Program;
+ engine->GetDiskThread()->OrderProgramChange(merged, this);
} else {
// TODO:
}
Index: src/engines/InstrumentManagerThread.cpp
===================================================================
--- src/engines/InstrumentManagerThread.cpp (revision 2276)
+++ src/engines/InstrumentManagerThread.cpp (arbetskopia)
@@ -53,12 +53,11 @@
}
- // already tell the engine which instrument to load
- pEngineChannel->PrepareLoadInstrument(Filename.c_str(),
uiInstrumentIndex);
-
command_t cmd;
cmd.type = command_t::DIRECT_LOAD;
cmd.pEngineChannel = pEngineChannel;
+ cmd.InstrumentIdx = uiInstrumentIndex;
+ cmd.InstrumentFile = Filename;
mutex.Lock();
queue.push_back(cmd);
@@ -116,6 +115,7 @@
switch (cmd.type) {
case command_t::DIRECT_LOAD:
EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, false);
+
cmd.pEngineChannel->PrepareLoadInstrument(cmd.InstrumentFile.c_str(),
cmd.InstrumentIdx);
cmd.pEngineChannel->LoadInstrument();
EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
break;
------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure contains a
definitive record of customers, application performance, security
threats, fraudulent activity and more. Splunk takes this data and makes
sense of it. Business sense. IT sense. Common sense.
http://p.sf.net/sfu/splunk-d2dcopy1
_______________________________________________
Linuxsampler-devel mailing list
Linuxsampler-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxsampler-devel