/[svn]/linuxsampler/trunk/src/drivers/midi/MidiInputPort.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/drivers/midi/MidiInputPort.cpp

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

revision 2425 by schoenebeck, Wed Nov 21 21:52:15 2012 UTC revision 2426 by schoenebeck, Fri Mar 1 23:00:17 2013 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *   Copyright (C) 2005 - 2012 Christian Schoenebeck                       *   *   Copyright (C) 2005 - 2013 Christian Schoenebeck                       *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
9   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 82  namespace LinuxSampler { Line 82  namespace LinuxSampler {
82      {      {
83          this->pDevice = pDevice;          this->pDevice = pDevice;
84          this->portNumber = portNumber;          this->portNumber = portNumber;
85            runningStatusBuf[0] = 0;
86          Parameters["NAME"] = new ParameterName(this);          Parameters["NAME"] = new ParameterName(this);
87      }      }
88    
# Line 377  namespace LinuxSampler { Line 378  namespace LinuxSampler {
378          }          }
379          MidiChannelMapReader.Unlock();          MidiChannelMapReader.Unlock();
380      }      }
381        
382        /**
383         * Handles the so called MIDI "running status" mode, which allows devices
384         * to reduce bandwidth (data reduction).
385         *
386         * If the passed in MIDI data is regular MIDI data, this method will simply
387         * return the original data pointer and just stores the status byte for
388         * potential "running status" event eventually coming next.
389         *
390         * If the passed in MIDI data however seems to be in "running status" mode,
391         * this method will return another buffer, which allows the MIDI parser
392         * to handle the MIDI data as usually with "normal" MIDI data.
393         */
394        uint8_t* MidiInputPort::handleRunningStatus(uint8_t* pData) {
395            if ((pData[0] & 0x80) || !runningStatusBuf[0]) {
396                // store status byte for eventual "running status" in next event
397                if (pData[0] & 0x80) {
398                    if (pData[0] < 0xf0) {
399                        // "running status" is only allowed for channel messages
400                        runningStatusBuf[0] = pData[0];
401                    } else if (pData[0] < 0xf8) {
402                        // "system common" messages (0xf0..0xf7) shall reset any running
403                        // status, however "realtime" messages (0xf8..0xff) shall be
404                        // ignored here
405                        runningStatusBuf[0] = 0;
406                    }
407                }
408                // it's either a regular status byte, or some invalid "running status"
409                return pData;
410            } else { // "running status" mode ...
411                const uint8_t type = runningStatusBuf[0] & 0xf0;
412                const int size = (type == 0xc0 || type == 0xd0) ? 1 : 2; // only program change & channel pressure have 1 data bytes
413                memcpy(&runningStatusBuf[1], pData, size);
414                return runningStatusBuf;
415            }
416        }
417    
418      void MidiInputPort::DispatchRaw(uint8_t* pData) {      void MidiInputPort::DispatchRaw(uint8_t* pData) {
419            pData = handleRunningStatus(pData);
420            
421          uint8_t channel = pData[0] & 0x0f;          uint8_t channel = pData[0] & 0x0f;
422          switch (pData[0] & 0xf0) {          switch (pData[0] & 0xf0) {
423          case 0x80:          case 0x80:
# Line 412  namespace LinuxSampler { Line 451  namespace LinuxSampler {
451      }      }
452    
453      void MidiInputPort::DispatchRaw(uint8_t* pData, int32_t FragmentPos) {      void MidiInputPort::DispatchRaw(uint8_t* pData, int32_t FragmentPos) {
454            pData = handleRunningStatus(pData);
455            
456          uint8_t channel = pData[0] & 0x0f;          uint8_t channel = pData[0] & 0x0f;
457          switch (pData[0] & 0xf0) {          switch (pData[0] & 0xf0) {
458          case 0x80:          case 0x80:

Legend:
Removed from v.2425  
changed lines
  Added in v.2426

  ViewVC Help
Powered by ViewVC