/[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 3561 by schoenebeck, Fri Aug 23 11:44:00 2019 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 controllers)                      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                          if (pChannel->GetMidiRpnController() >= 0) { // RPN controller number was sent previously ...  
1490                              dmsg(4,("Guess it's an RPN ...\n"));                          // look-ahead: if next MIDI event is data entry LSB,
1491                              if (pChannel->GetMidiRpnController() == 2) { // coarse tuning in half tones                          // then skip this event here for now (to avoid double
1492                                  int transpose = (int) itControlChangeEvent->Param.CC.Value - 64;                          // handling of what's supposed to be one RPN/NRPN event)
1493                                  // limit to +- two octaves for now                          if (isNextEventCCNr(itControlChangeEvent, 38))
1494                                  transpose = RTMath::Min(transpose,  24);                              break;
1495                                  transpose = RTMath::Max(transpose, -24);  
1496                                  pChannel->GlobalTranspose = transpose;                          if (pChannel->GetMidiRpnParameter() >= 0) { // RPN parameter number was sent previously ...
1497                                  // workaround, so we won't have hanging notes                              int ch = itControlChangeEvent->Param.CC.Channel;
1498                                  pChannel->ReleaseAllVoices(itControlChangeEvent);                              int param = pChannel->GetMidiRpnParameter();
1499                              }                              int value = itControlChangeEvent->Param.CC.Value << 7;
1500                              // to prevent other MIDI CC #6 messages to be misenterpreted as RPN controller data  
1501                              pChannel->ResetMidiRpnController();                              // transform event type: CC event -> RPN event
1502                          } else if (pChannel->GetMidiNrpnController() >= 0) { // NRPN controller number was sent previously ...                              itControlChangeEvent->Type = Event::type_rpn;
1503                              dmsg(4,("Guess it's an NRPN ...\n"));                              itControlChangeEvent->Param.RPN.Channel = ch;
1504                              const int NrpnCtrlMSB = pChannel->GetMidiNrpnController() >> 8;                              itControlChangeEvent->Param.RPN.Parameter = param;
1505                              const int NrpnCtrlLSB = pChannel->GetMidiNrpnController() & 0xff;                              itControlChangeEvent->Param.RPN.Value = value;
1506                              dmsg(4,("NRPN MSB=%d LSB=%d Data=%d\n", NrpnCtrlMSB, NrpnCtrlLSB, itControlChangeEvent->Param.CC.Value));  
1507                              switch (NrpnCtrlMSB) {                              // do the actual RPN event processing
1508                                  case 0x1a: { // volume level of note (Roland GS NRPN)                              ProcessHardcodedRpn(pEngineChannel, itControlChangeEvent);
1509                                      const uint note = NrpnCtrlLSB;  
1510                                      const uint vol  = itControlChangeEvent->Param.CC.Value;                              // to prevent other data entry messages to be misenterpreted as RPN value
1511                                      dmsg(4,("Note Volume NRPN received (note=%d,vol=%d).\n", note, vol));                              pChannel->ResetMidiRpnParameter();
1512                                      if (note < 128 && vol < 128)                          } else if (pChannel->GetMidiNrpnParameter() >= 0) { // NRPN parameter number was sent previously ...
1513                                          pChannel->pMIDIKeyInfo[note].Volume = VolumeCurve[vol];                              int ch = itControlChangeEvent->Param.CC.Channel;
1514                                      break;                              int param = pChannel->GetMidiNrpnParameter();
1515                                  }                              int value = itControlChangeEvent->Param.CC.Value << 7;
1516                                  case 0x1c: { // panpot of note (Roland GS NRPN)  
1517                                      const uint note = NrpnCtrlLSB;                              // transform event type: CC event -> NRPN event
1518                                      const uint pan  = itControlChangeEvent->Param.CC.Value;                              itControlChangeEvent->Type = Event::type_nrpn;
1519                                      dmsg(4,("Note Pan NRPN received (note=%d,pan=%d).\n", note, pan));                              itControlChangeEvent->Param.RPN.Channel = ch;
1520                                      if (note < 128 && pan < 128) {                              itControlChangeEvent->Param.RPN.Parameter = param;
1521                                          pChannel->pMIDIKeyInfo[note].PanLeft  = PanCurve[128 - pan];                              itControlChangeEvent->Param.RPN.Value = value;
1522                                          pChannel->pMIDIKeyInfo[note].PanRight = PanCurve[pan];  
1523                                      }                              // do the actual NRPN event processing
1524                                      break;                              ProcessHardcodedNrpn(pEngineChannel, itControlChangeEvent);
1525                                  }  
1526                                  case 0x1d: { // reverb send of note (Roland GS NRPN)                              // to prevent other data entry messages to be misenterpreted as NRPN value
1527                                      const uint note = NrpnCtrlLSB;                              pChannel->ResetMidiNrpnParameter();
                                     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 = NrpnCtrlLSB;  
                                     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 controller data  
                             pChannel->ResetMidiNrpnController();  
1528                          }                          }
1529                          break;                          break;
1530                      }                      }
# 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 1629  namespace LinuxSampler { Line 1656  namespace LinuxSampler {
1656                          }                          }
1657                          break;                          break;
1658                      }                      }
1659                      case 98: { // NRPN controller LSB                      case 98: { // NRPN parameter LSB
1660                          dmsg(4,("NRPN LSB %d\n", itControlChangeEvent->Param.CC.Value));                          dmsg(4,("NRPN LSB %d\n", itControlChangeEvent->Param.CC.Value));
1661                          pEngineChannel->SetMidiNrpnControllerLsb(itControlChangeEvent->Param.CC.Value);                          pEngineChannel->SetMidiNrpnParameterLsb(itControlChangeEvent->Param.CC.Value);
1662                          break;                          break;
1663                      }                      }
1664                      case 99: { // NRPN controller MSB                      case 99: { // NRPN parameter MSB
1665                          dmsg(4,("NRPN MSB %d\n", itControlChangeEvent->Param.CC.Value));                          dmsg(4,("NRPN MSB %d\n", itControlChangeEvent->Param.CC.Value));
1666                          pEngineChannel->SetMidiNrpnControllerMsb(itControlChangeEvent->Param.CC.Value);                          pEngineChannel->SetMidiNrpnParameterMsb(itControlChangeEvent->Param.CC.Value);
1667                          break;                          break;
1668                      }                      }
1669                      case 100: { // RPN controller LSB                      case 100: { // RPN parameter LSB
1670                          dmsg(4,("RPN LSB %d\n", itControlChangeEvent->Param.CC.Value));                          dmsg(4,("RPN LSB %d\n", itControlChangeEvent->Param.CC.Value));
1671                          pEngineChannel->SetMidiRpnControllerLsb(itControlChangeEvent->Param.CC.Value);                          pEngineChannel->SetMidiRpnParameterLsb(itControlChangeEvent->Param.CC.Value);
1672                          break;                          break;
1673                      }                      }
1674                      case 101: { // RPN controller MSB                      case 101: { // RPN parameter MSB
1675                          dmsg(4,("RPN MSB %d\n", itControlChangeEvent->Param.CC.Value));                          dmsg(4,("RPN MSB %d\n", itControlChangeEvent->Param.CC.Value));
1676                          pEngineChannel->SetMidiRpnControllerMsb(itControlChangeEvent->Param.CC.Value);                          pEngineChannel->SetMidiRpnParameterMsb(itControlChangeEvent->Param.CC.Value);
1677                          break;                          break;
1678                      }                      }
1679    
# 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.3561  
changed lines
  Added in v.3688

  ViewVC Help
Powered by ViewVC