/[svn]/linuxsampler/trunk/src/engines/EngineBase.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/EngineBase.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3687 by schoenebeck, Thu Jan 2 22:37:07 2020 UTC revision 3688 by schoenebeck, Thu Jan 2 23:47:42 2020 UTC
# Line 1484  namespace LinuxSampler { Line 1484  namespace LinuxSampler {
1484                          pChannel->PortamentoTime = (float) itControlChangeEvent->Param.CC.Value / 127.0f * (float) CONFIG_PORTAMENTO_TIME_MAX + (float) CONFIG_PORTAMENTO_TIME_MIN;                          pChannel->PortamentoTime = (float) itControlChangeEvent->Param.CC.Value / 127.0f * (float) CONFIG_PORTAMENTO_TIME_MAX + (float) CONFIG_PORTAMENTO_TIME_MIN;
1485                          break;                          break;
1486                      }                      }
1487                      case 6: { // data entry (currently only used for RPN and NRPN parameters)                      case 6: { // data entry (MSB)
1488                          //dmsg(1,("DATA ENTRY %d\n", itControlChangeEvent->Param.CC.Value));                          //dmsg(1,("DATA ENTRY MSB %d\n", itControlChangeEvent->Param.CC.Value));
1489    
1490                            // look-ahead: if next MIDI event is data entry LSB,
1491                            // then skip this event here for now (to avoid double
1492                            // handling of what's supposed to be one RPN/NRPN event)
1493                            if (isNextEventCCNr(itControlChangeEvent, 38))
1494                                break;
1495    
1496                          if (pChannel->GetMidiRpnParameter() >= 0) { // RPN parameter number was sent previously ...                          if (pChannel->GetMidiRpnParameter() >= 0) { // RPN parameter number was sent previously ...
1497                              dmsg(4,("Guess it's an RPN ...\n"));                              int ch = itControlChangeEvent->Param.CC.Channel;
1498                              if (pChannel->GetMidiRpnParameter() == 2) { // coarse tuning in half tones                              int param = pChannel->GetMidiRpnParameter();
1499                                  int transpose = (int) itControlChangeEvent->Param.CC.Value - 64;                              int value = itControlChangeEvent->Param.CC.Value << 7;
1500                                  // limit to +- two octaves for now  
1501                                  transpose = RTMath::Min(transpose,  24);                              // transform event type: CC event -> RPN event
1502                                  transpose = RTMath::Max(transpose, -24);                              itControlChangeEvent->Type = Event::type_rpn;
1503                                  pChannel->GlobalTranspose = transpose;                              itControlChangeEvent->Param.RPN.Channel = ch;
1504                                  // workaround, so we won't have hanging notes                              itControlChangeEvent->Param.RPN.Parameter = param;
1505                                  pChannel->ReleaseAllVoices(itControlChangeEvent);                              itControlChangeEvent->Param.RPN.Value = value;
1506                              }  
1507                              // to prevent other MIDI CC #6 messages to be misenterpreted as RPN value                              // do the actual RPN event processing
1508                                ProcessHardcodedRpn(pEngineChannel, itControlChangeEvent);
1509    
1510                                // to prevent other data entry messages to be misenterpreted as RPN value
1511                              pChannel->ResetMidiRpnParameter();                              pChannel->ResetMidiRpnParameter();
1512                          } else if (pChannel->GetMidiNrpnParameter() >= 0) { // NRPN parameter number was sent previously ...                          } else if (pChannel->GetMidiNrpnParameter() >= 0) { // NRPN parameter number was sent previously ...
1513                              dmsg(4,("Guess it's an NRPN ...\n"));                              int ch = itControlChangeEvent->Param.CC.Channel;
1514                              const int NrpnMSB = pChannel->GetMidiNrpnParameter() >> 7;                              int param = pChannel->GetMidiNrpnParameter();
1515                              const int NrpnLSB = pChannel->GetMidiNrpnParameter() & 127;                              int value = itControlChangeEvent->Param.CC.Value << 7;
1516                              dmsg(4,("NRPN MSB=%d LSB=%d Data=%d\n", NrpnMSB, NrpnLSB, itControlChangeEvent->Param.CC.Value));  
1517                              switch (NrpnMSB) {                              // transform event type: CC event -> NRPN event
1518                                  case 0x1a: { // volume level of note (Roland GS NRPN)                              itControlChangeEvent->Type = Event::type_nrpn;
1519                                      const uint note = NrpnLSB;                              itControlChangeEvent->Param.RPN.Channel = ch;
1520                                      const uint vol  = itControlChangeEvent->Param.CC.Value;                              itControlChangeEvent->Param.RPN.Parameter = param;
1521                                      dmsg(4,("Note Volume NRPN received (note=%d,vol=%d).\n", note, vol));                              itControlChangeEvent->Param.RPN.Value = value;
1522                                      if (note < 128 && vol < 128)  
1523                                          pChannel->pMIDIKeyInfo[note].Volume = VolumeCurve[vol];                              // do the actual NRPN event processing
1524                                      break;                              ProcessHardcodedNrpn(pEngineChannel, itControlChangeEvent);
1525                                  }  
1526                                  case 0x1c: { // panpot of note (Roland GS NRPN)                              // to prevent other data entry messages to be misenterpreted as NRPN value
                                     const uint note = NrpnLSB;  
                                     const uint pan  = itControlChangeEvent->Param.CC.Value;  
                                     dmsg(4,("Note Pan NRPN received (note=%d,pan=%d).\n", note, pan));  
                                     if (note < 128 && pan < 128) {  
                                         pChannel->pMIDIKeyInfo[note].PanLeft  = PanCurve[128 - pan];  
                                         pChannel->pMIDIKeyInfo[note].PanRight = PanCurve[pan];  
                                     }  
                                     break;  
                                 }  
                                 case 0x1d: { // reverb send of note (Roland GS NRPN)  
                                     const uint note = NrpnLSB;  
                                     const float reverb = float(itControlChangeEvent->Param.CC.Value) / 127.0f;  
                                     dmsg(4,("Note Reverb Send NRPN received (note=%d,send=%f).\n", note, reverb));  
                                     if (note < 128)  
                                         pChannel->pMIDIKeyInfo[note].ReverbSend = reverb;  
                                     break;  
                                 }  
                                 case 0x1e: { // chorus send of note (Roland GS NRPN)  
                                     const uint note = NrpnLSB;  
                                     const float chorus = float(itControlChangeEvent->Param.CC.Value) / 127.0f;  
                                     dmsg(4,("Note Chorus Send NRPN received (note=%d,send=%f).\n", note, chorus));  
                                     if (note < 128)  
                                         pChannel->pMIDIKeyInfo[note].ChorusSend = chorus;  
                                     break;  
                                 }  
                             }  
                             // to prevent other MIDI CC #6 messages to be misenterpreted as NRPN value  
1527                              pChannel->ResetMidiNrpnParameter();                              pChannel->ResetMidiNrpnParameter();
1528                          }                          }
1529                          break;                          break;
# Line 1556  namespace LinuxSampler { Line 1539  namespace LinuxSampler {
1539                          pChannel->iLastPanRequest = itControlChangeEvent->Param.CC.Value;                          pChannel->iLastPanRequest = itControlChangeEvent->Param.CC.Value;
1540                          break;                          break;
1541                      }                      }
1542                        case 38: { // data entry (LSB)
1543                            //dmsg(1,("DATA ENTRY LSB %d\n", itControlChangeEvent->Param.CC.Value));
1544                            int value = 0;
1545    
1546                            // look-back: if previous MIDI event was data entry MSB,
1547                            // then obtain that value for the MSB value portion
1548                            if (isPrevEventCCNr(itControlChangeEvent, 6))
1549                                value = prevEventOf(itControlChangeEvent)->Param.CC.Value << 7;
1550    
1551                            if (pChannel->GetMidiRpnParameter() >= 0) { // RPN parameter number was sent previously ...
1552                                int ch = itControlChangeEvent->Param.CC.Channel;
1553                                int param = pChannel->GetMidiRpnParameter();
1554                                value |= itControlChangeEvent->Param.CC.Value;
1555    
1556                                // transform event type: CC event -> RPN event
1557                                itControlChangeEvent->Type = Event::type_rpn;
1558                                itControlChangeEvent->Param.RPN.Channel = ch;
1559                                itControlChangeEvent->Param.RPN.Parameter = param;
1560                                itControlChangeEvent->Param.RPN.Value = value;
1561    
1562                                // do the actual RPN event processing
1563                                ProcessHardcodedRpn(pEngineChannel, itControlChangeEvent);
1564    
1565                                // to prevent other data entry messages to be misenterpreted as RPN value
1566                                pChannel->ResetMidiRpnParameter();
1567                            } else if (pChannel->GetMidiNrpnParameter() >= 0) { // NRPN parameter number was sent previously ...
1568                                int ch = itControlChangeEvent->Param.CC.Channel;
1569                                int param = pChannel->GetMidiNrpnParameter();
1570                                value |= itControlChangeEvent->Param.CC.Value;
1571    
1572                                // transform event type: CC event -> NRPN event
1573                                itControlChangeEvent->Type = Event::type_nrpn;
1574                                itControlChangeEvent->Param.RPN.Channel = ch;
1575                                itControlChangeEvent->Param.RPN.Parameter = param;
1576                                itControlChangeEvent->Param.RPN.Value = value;
1577    
1578                                // do the actual NRPN event processing
1579                                ProcessHardcodedNrpn(pEngineChannel, itControlChangeEvent);
1580    
1581                                // to prevent other data entry messages to be misenterpreted as NRPN value
1582                                pChannel->ResetMidiNrpnParameter();
1583                            }
1584                            break;
1585                        }
1586                      case 64: { // sustain                      case 64: { // sustain
1587                          if (itControlChangeEvent->Param.CC.Value >= 64 && !pChannel->SustainPedal) {                          if (itControlChangeEvent->Param.CC.Value >= 64 && !pChannel->SustainPedal) {
1588                              dmsg(4,("DAMPER (RIGHT) PEDAL DOWN\n"));                              dmsg(4,("DAMPER (RIGHT) PEDAL DOWN\n"));
# Line 1680  namespace LinuxSampler { Line 1707  namespace LinuxSampler {
1707                          break;                          break;
1708                      }                      }
1709                  }                  }
1710                }
1711    
1712                /**
1713                 * Process MIDI RPN events with hard coded behavior.
1714                 *
1715                 * @param pEngineChannel - engine channel on which the MIDI RPN
1716                 *                         event was received
1717                 * @param itRpnEvent - the actual MIDI RPN event
1718                 */
1719                void ProcessHardcodedRpn(EngineChannel* pEngineChannel,
1720                                         Pool<Event>::Iterator& itRpnEvent)
1721                {
1722                    EngineChannelBase<V, R, I>* pChannel =
1723                        static_cast<EngineChannelBase<V, R, I>*>(pEngineChannel);
1724    
1725                    if (itRpnEvent->Param.RPN.Parameter == 2) { // coarse tuning in half tones
1726                        int transpose = (int) itRpnEvent->Param.RPN.ValueMSB() - 64;
1727                        // limit to +- two octaves for now
1728                        transpose = RTMath::Min(transpose,  24);
1729                        transpose = RTMath::Max(transpose, -24);
1730                        pChannel->GlobalTranspose = transpose;
1731                        // workaround, so we won't have hanging notes
1732                        pChannel->ReleaseAllVoices(itRpnEvent);
1733                    }
1734                }
1735    
1736                /**
1737                 * Process MIDI NRPN events with hard coded behavior.
1738                 *
1739                 * @param pEngineChannel - engine channel on which the MIDI NRPN
1740                 *                         event was received
1741                 * @param itRpnEvent - the actual MIDI NRPN event
1742                 */
1743                void ProcessHardcodedNrpn(EngineChannel* pEngineChannel,
1744                                          Pool<Event>::Iterator& itNrpnEvent)
1745                {
1746                    EngineChannelBase<V, R, I>* pChannel =
1747                        static_cast<EngineChannelBase<V, R, I>*>(pEngineChannel);
1748    
1749                    switch (itNrpnEvent->Param.NRPN.ParameterMSB()) {
1750                        case 0x1a: { // volume level of note (Roland GS NRPN)
1751                            const uint note = itNrpnEvent->Param.NRPN.ParameterLSB();
1752                            const uint vol  = itNrpnEvent->Param.NRPN.ValueMSB();
1753                            dmsg(4,("Note Volume NRPN received (note=%d,vol=%d).\n", note, vol));
1754                            if (note < 128 && vol < 128)
1755                                pChannel->pMIDIKeyInfo[note].Volume = VolumeCurve[vol];
1756                            break;
1757                        }
1758                        case 0x1c: { // panpot of note (Roland GS NRPN)
1759                            const uint note = itNrpnEvent->Param.NRPN.ParameterLSB();
1760                            const uint pan  = itNrpnEvent->Param.NRPN.ValueMSB();
1761                            dmsg(4,("Note Pan NRPN received (note=%d,pan=%d).\n", note, pan));
1762                            if (note < 128 && pan < 128) {
1763                                pChannel->pMIDIKeyInfo[note].PanLeft  = PanCurve[128 - pan];
1764                                pChannel->pMIDIKeyInfo[note].PanRight = PanCurve[pan];
1765                            }
1766                            break;
1767                        }
1768                        case 0x1d: { // reverb send of note (Roland GS NRPN)
1769                            const uint note = itNrpnEvent->Param.NRPN.ParameterLSB();
1770                            const float reverb = float(itNrpnEvent->Param.NRPN.Value) / 16383.f;
1771                            dmsg(4,("Note Reverb Send NRPN received (note=%d,send=%f).\n", note, reverb));
1772                            if (note < 128)
1773                                pChannel->pMIDIKeyInfo[note].ReverbSend = reverb;
1774                            break;
1775                        }
1776                        case 0x1e: { // chorus send of note (Roland GS NRPN)
1777                            const uint note = itNrpnEvent->Param.NRPN.ParameterLSB();
1778                            const float chorus = float(itNrpnEvent->Param.NRPN.Value) / 16383.f;
1779                            dmsg(4,("Note Chorus Send NRPN received (note=%d,send=%f).\n", note, chorus));
1780                            if (note < 128)
1781                                pChannel->pMIDIKeyInfo[note].ChorusSend = chorus;
1782                            break;
1783                        }
1784                    }
1785              }              }
1786    
1787              virtual D* CreateDiskThread() = 0;              virtual D* CreateDiskThread() = 0;

Legend:
Removed from v.3687  
changed lines
  Added in v.3688

  ViewVC Help
Powered by ViewVC