51 |
if (engines.count(pDevice)) { |
if (engines.count(pDevice)) { |
52 |
dmsg(4,("Using existing gig::Engine.\n")); |
dmsg(4,("Using existing gig::Engine.\n")); |
53 |
pEngine = engines[pDevice]; |
pEngine = engines[pDevice]; |
54 |
|
|
55 |
|
// Disable the engine while the new engine channel is |
56 |
|
// added and initialized. The engine will be enabled again |
57 |
|
// in EngineChannel::Connect. |
58 |
|
pEngine->DisableAndLock(); |
59 |
} else { // create a new engine (and disk thread) instance for the given audio output device |
} else { // create a new engine (and disk thread) instance for the given audio output device |
60 |
dmsg(4,("Creating new gig::Engine.\n")); |
dmsg(4,("Creating new gig::Engine.\n")); |
61 |
pEngine = (Engine*) EngineFactory::Create("gig"); |
pEngine = (Engine*) EngineFactory::Create("gig"); |
62 |
pEngine->Connect(pDevice); |
pEngine->Connect(pDevice); |
63 |
engines[pDevice] = pEngine; |
engines[pDevice] = pEngine; |
64 |
} |
} |
|
|
|
65 |
// register engine channel to the engine instance |
// register engine channel to the engine instance |
|
|
|
|
// Disable the engine while the new engine channel is added |
|
|
// and initialized. The engine will be enabled again in |
|
|
// EngineChannel::Connect. |
|
|
pEngine->DisableAndLock(); |
|
|
|
|
66 |
pEngine->engineChannels.add(pChannel); |
pEngine->engineChannels.add(pChannel); |
67 |
// remember index in the ArrayList |
// remember index in the ArrayList |
68 |
pChannel->iEngineIndexSelf = pEngine->engineChannels.size() - 1; |
pChannel->iEngineIndexSelf = pEngine->engineChannels.size() - 1; |
709 |
|
|
710 |
if (!pEngineChannel->pInstrument) return; // ignore if no instrument loaded |
if (!pEngineChannel->pInstrument) return; // ignore if no instrument loaded |
711 |
|
|
712 |
|
//HACK: we should better add the transpose value only to the most mandatory places (like for retrieving the region and calculating the tuning), because otherwise voices will unintendedly survive when changing transpose while playing |
713 |
|
itNoteOnEvent->Param.Note.Key += pEngineChannel->GlobalTranspose; |
714 |
|
|
715 |
const int key = itNoteOnEvent->Param.Note.Key; |
const int key = itNoteOnEvent->Param.Note.Key; |
716 |
midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[key]; |
midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[key]; |
717 |
|
|
799 |
if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted |
if (pEngineChannel->GetMute()) return; // skip if sampler channel is muted |
800 |
#endif |
#endif |
801 |
|
|
802 |
|
//HACK: we should better add the transpose value only to the most mandatory places (like for retrieving the region and calculating the tuning), because otherwise voices will unintendedly survive when changing transpose while playing |
803 |
|
itNoteOffEvent->Param.Note.Key += pEngineChannel->GlobalTranspose; |
804 |
|
|
805 |
const int iKey = itNoteOffEvent->Param.Note.Key; |
const int iKey = itNoteOffEvent->Param.Note.Key; |
806 |
midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[iKey]; |
midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[iKey]; |
807 |
pKey->KeyPressed = false; // the MIDI key was now released |
pKey->KeyPressed = false; // the MIDI key was now released |
1362 |
pEngineChannel->PortamentoTime = (float) itControlChangeEvent->Param.CC.Value / 127.0f * (float) CONFIG_PORTAMENTO_TIME_MAX + (float) CONFIG_PORTAMENTO_TIME_MIN; |
pEngineChannel->PortamentoTime = (float) itControlChangeEvent->Param.CC.Value / 127.0f * (float) CONFIG_PORTAMENTO_TIME_MAX + (float) CONFIG_PORTAMENTO_TIME_MIN; |
1363 |
break; |
break; |
1364 |
} |
} |
1365 |
|
case 6: { // data entry (currently only used for RPN controllers) |
1366 |
|
if (pEngineChannel->GetMidiRpnController() == 2) { // coarse tuning in half tones |
1367 |
|
int transpose = (int) itControlChangeEvent->Param.CC.Value - 64; |
1368 |
|
// limit to +- two octaves for now |
1369 |
|
transpose = RTMath::Min(transpose, 24); |
1370 |
|
transpose = RTMath::Max(transpose, -24); |
1371 |
|
pEngineChannel->GlobalTranspose = transpose; |
1372 |
|
} |
1373 |
|
break; |
1374 |
|
} |
1375 |
case 7: { // volume |
case 7: { // volume |
1376 |
//TODO: not sample accurate yet |
//TODO: not sample accurate yet |
1377 |
pEngineChannel->MidiVolume = VolumeCurve[itControlChangeEvent->Param.CC.Value]; |
pEngineChannel->MidiVolume = VolumeCurve[itControlChangeEvent->Param.CC.Value]; |
1476 |
} |
} |
1477 |
break; |
break; |
1478 |
} |
} |
1479 |
|
case 100: { // RPN controller LSB |
1480 |
|
pEngineChannel->SetMidiRpnControllerLsb(itControlChangeEvent->Param.CC.Value); |
1481 |
|
break; |
1482 |
|
} |
1483 |
|
case 101: { // RPN controller MSB |
1484 |
|
pEngineChannel->SetMidiRpnControllerMsb(itControlChangeEvent->Param.CC.Value); |
1485 |
|
break; |
1486 |
|
} |
1487 |
|
|
1488 |
|
|
1489 |
// Channel Mode Messages |
// Channel Mode Messages |
1716 |
} |
} |
1717 |
|
|
1718 |
String Engine::Version() { |
String Engine::Version() { |
1719 |
String s = "$Revision: 1.71 $"; |
String s = "$Revision: 1.73 $"; |
1720 |
return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword |
return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword |
1721 |
} |
} |
1722 |
|
|