Merge pull request #804 from diizy/midioffset

Make MIDI timing sample-accurate
This commit is contained in:
Tobias Doerffel
2014-06-04 09:35:11 +02:00
13 changed files with 34 additions and 32 deletions

View File

@@ -23,8 +23,8 @@
*
*/
#ifndef _INSTRUMENT_H
#define _INSTRUMENT_H
#ifndef INSTRUMENT_H
#define INSTRUMENT_H
#include <QtGui/QWidget>
@@ -101,7 +101,7 @@ public:
// sub-classes can re-implement this for receiving all incoming
// MIDI-events
inline virtual bool handleMidiEvent( const MidiEvent&, const MidiTime& = MidiTime() )
inline virtual bool handleMidiEvent( const MidiEvent&, const MidiTime& = MidiTime(), f_cnt_t offset = 0 )
{
return true;
}

View File

@@ -23,8 +23,8 @@
*
*/
#ifndef _INSTRUMENT_TRACK_H
#define _INSTRUMENT_TRACK_H
#ifndef INSTRUMENT_TRACK_H
#define INSTRUMENT_TRACK_H
#include "AudioPort.h"
#include "InstrumentFunctions.h"
@@ -71,8 +71,8 @@ public:
MidiEvent applyMasterKey( const MidiEvent& event );
virtual void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime() );
virtual void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime() );
virtual void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 );
virtual void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 );
// silence all running notes played by this track
void silenceAllNotes();

View File

@@ -22,8 +22,8 @@
*
*/
#ifndef _MIDI_CONTROLLER_H
#define _MIDI_CONTROLLER_H
#ifndef MIDI_CONTROLLER_H
#define MIDI_CONTROLLER_H
#include <QtGui/QWidget>
@@ -44,10 +44,10 @@ public:
virtual ~MidiController();
virtual void processInEvent( const MidiEvent & _me,
const MidiTime & _time );
const MidiTime & _time, f_cnt_t offset = 0 );
virtual void processOutEvent( const MidiEvent& _me,
const MidiTime & _time)
const MidiTime & _time, f_cnt_t offset = 0 )
{
// No output yet
}

View File

@@ -22,8 +22,8 @@
*
*/
#ifndef _MIDI_EVENT_PROCESSOR_H
#define _MIDI_EVENT_PROCESSOR_H
#ifndef MIDI_EVENT_PROCESSOR_H
#define MIDI_EVENT_PROCESSOR_H
#include "MidiEvent.h"
#include "MidiTime.h"
@@ -42,8 +42,8 @@ public:
}
// to be implemented by inheriting classes
virtual void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime() ) = 0;
virtual void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime() ) = 0;
virtual void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 ) = 0;
virtual void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 ) = 0;
} ;

View File

@@ -283,7 +283,7 @@ int opl2instrument::pushVoice(int v) {
return i;
}
bool opl2instrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time )
bool opl2instrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset )
{
emulatorMutex.lock();
int key, vel, voice, tmp_pb;

View File

@@ -53,7 +53,7 @@ public:
return IsSingleStreamed | IsMidiBased;
}
virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time );
virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset = 0 );
virtual void play( sampleFrame * _working_buffer );
void saveSettings( QDomDocument & _doc, QDomElement & _this );

View File

@@ -310,12 +310,12 @@ void vestigeInstrument::play( sampleFrame * _buf )
bool vestigeInstrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time )
bool vestigeInstrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset )
{
m_pluginMutex.lock();
if( m_plugin != NULL )
{
m_plugin->processMidiEvent( event, time );
m_plugin->processMidiEvent( event, offset );
}
m_pluginMutex.unlock();

View File

@@ -68,7 +68,7 @@ public:
return IsSingleStreamed | IsMidiBased;
}
virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time );
virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset = 0 );
virtual PluginView * instantiateView( QWidget * _parent );

View File

@@ -343,7 +343,7 @@ void ZynAddSubFxInstrument::play( sampleFrame * _buf )
bool ZynAddSubFxInstrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time )
bool ZynAddSubFxInstrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset )
{
// do not forward external MIDI Control Change events if the according
// LED is not checked

View File

@@ -70,7 +70,7 @@ public:
virtual void play( sampleFrame * _working_buffer );
virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time = MidiTime() );
virtual bool handleMidiEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 );
virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent );
virtual void loadSettings( const QDomElement & _this );

View File

@@ -107,7 +107,8 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack,
// send MidiNoteOn event
m_instrumentTrack->processOutEvent(
MidiEvent( MidiNoteOn, midiChannel(), midiKey(), midiVelocity( baseVelocity ) ),
MidiTime::fromFrames( offset(), engine::framesPerTick() ) );
MidiTime::fromFrames( offset(), engine::framesPerTick() ),
offset() );
}
}
@@ -336,7 +337,8 @@ void NotePlayHandle::noteOff( const f_cnt_t _s )
// send MidiNoteOff event
m_instrumentTrack->processOutEvent(
MidiEvent( MidiNoteOff, midiChannel(), midiKey(), 0 ),
MidiTime::fromFrames( m_framesBeforeRelease, engine::framesPerTick() ) );
MidiTime::fromFrames( m_framesBeforeRelease, engine::framesPerTick() ),
_s );
}
// inform attached components about MIDI finished (used for recording in Piano Roll)

View File

@@ -73,7 +73,7 @@ void MidiController::updateName()
void MidiController::processInEvent( const MidiEvent& event, const MidiTime& time )
void MidiController::processInEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset )
{
unsigned char controllerNum;
switch( event.type() )

View File

@@ -232,7 +232,7 @@ MidiEvent InstrumentTrack::applyMasterKey( const MidiEvent& event )
void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& time )
void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset )
{
engine::mixer()->lock();
@@ -335,7 +335,7 @@ void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& ti
break;
}
if( eventHandled == false && instrument()->handleMidiEvent( event, time ) == false )
if( eventHandled == false && instrument()->handleMidiEvent( event, time, offset ) == false )
{
qWarning( "InstrumentTrack: unhandled MIDI event %d", event.type() );
}
@@ -346,7 +346,7 @@ void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& ti
void InstrumentTrack::processOutEvent( const MidiEvent& event, const MidiTime& time )
void InstrumentTrack::processOutEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset )
{
// do nothing if we do not have an instrument instance (e.g. when loading settings)
if( m_instrument == NULL )
@@ -366,10 +366,10 @@ void InstrumentTrack::processOutEvent( const MidiEvent& event, const MidiTime& t
{
if( m_runningMidiNotes[key] > 0 )
{
m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time );
m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time, offset );
}
++m_runningMidiNotes[key];
m_instrument->handleMidiEvent( MidiEvent( MidiNoteOn, midiPort()->realOutputChannel(), key, event.velocity() ), time );
m_instrument->handleMidiEvent( MidiEvent( MidiNoteOn, midiPort()->realOutputChannel(), key, event.velocity() ), time, offset );
emit newNote();
}
@@ -381,12 +381,12 @@ void InstrumentTrack::processOutEvent( const MidiEvent& event, const MidiTime& t
if( key >= 0 && key < NumKeys && --m_runningMidiNotes[key] <= 0 )
{
m_runningMidiNotes[key] = qMax( 0, m_runningMidiNotes[key] );
m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time );
m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time, offset );
}
break;
default:
m_instrument->handleMidiEvent( transposedEvent, time );
m_instrument->handleMidiEvent( transposedEvent, time, offset );
break;
}