Skip to content

Commit

Permalink
Merge pull request #171 from blablack/cymbal_choke
Browse files Browse the repository at this point in the history
Midi input and cymbal choke
  • Loading branch information
mauser committed Aug 4, 2014
2 parents 25b017c + da3c61d commit 15b5808
Show file tree
Hide file tree
Showing 14 changed files with 316 additions and 53 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -6,3 +6,5 @@ moc_*.cc
/libs/hydrogen/include/hydrogen/config.h
/cmake_opts
/hydrogen
*.cbp
*.layout
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions data/xsd/drumkit.xsd
Expand Up @@ -61,6 +61,9 @@
<xsd:element name="midiOutChannel" type="xsd:integer" default="-1" minOccurs="0"/>
<xsd:element name="midiOutNote" type="xsd:integer" minOccurs="0"/>
<xsd:element name="isStopNote" type="h2:bool" default="false" minOccurs="0"/>
<xsd:element name="isHihat" type="h2:bool" default="false"/>
<xsd:element name="lower_cc" type="xsd:integer" default="0"/>
<xsd:element name="higher_cc" type="xsd:integer" default="0"/>
<xsd:element name="FX1Level" type="xsd:decimal" default="0.0" minOccurs="0"/>
<xsd:element name="FX2Level" type="xsd:decimal" default="0.0" minOccurs="0"/>
<xsd:element name="FX3Level" type="xsd:decimal" default="0.0" minOccurs="0"/>
Expand Down
5 changes: 4 additions & 1 deletion src/core/include/hydrogen/IO/MidiInput.h
Expand Up @@ -51,19 +51,22 @@ class MidiInput : public virtual Object
void handleSysexMessage( const MidiMessage& msg );
void handleControlChangeMessage( const MidiMessage& msg );
void handleProgramChangeMessage( const MidiMessage& msg );
void handlePolyphonicKeyPressureMessage( const MidiMessage& msg );

protected:
bool m_bActive;

void handleNoteOnMessage( const MidiMessage& msg );
void handleNoteOffMessage( const MidiMessage& msg );
void handleNoteOffMessage( const MidiMessage& msg, bool CymbalChoke );


private:
unsigned long __noteOnTick;
unsigned long __noteOffTick;
unsigned long computeDeltaNoteOnOfftime();

int __hihat_cc_openess;



};
Expand Down
42 changes: 42 additions & 0 deletions src/core/include/hydrogen/basics/instrument.h
Expand Up @@ -237,6 +237,15 @@ class Instrument : public H2Core::Object
/** get the stop notes of the instrument */
bool is_stop_notes() const;

void set_hihat( bool ishihat );
bool is_hihat() const;

void set_lower_cc( int message );
int get_lower_cc() const;

void set_higher_cc( int message );
int get_higher_cc() const;

///< set the name of the related drumkit
void set_drumkit_name( const QString& name );
///< get the name of the related drumkits
Expand Down Expand Up @@ -268,6 +277,9 @@ class Instrument : public H2Core::Object
int __queued; ///< count the number of notes queued within Sampler::__playing_notes_queue or std::priority_queue m_songNoteQueue
float __fx_level[MAX_FX]; ///< Ladspa FX level array
InstrumentLayer* __layers[MAX_LAYERS]; ///< InstrumentLayer array
bool __hihat; ///< the instrument is a hihat
int __lower_cc; ///< lower cc level
int __higher_cc; ///< higher cc level
};

// DEFINITIONS
Expand Down Expand Up @@ -506,6 +518,36 @@ inline bool Instrument::is_stop_notes() const
return __stop_notes;
}

inline void Instrument::set_hihat( bool ishihat )
{
__hihat = ishihat;
}

inline bool Instrument::is_hihat() const
{
return __hihat;
}

inline void Instrument::set_lower_cc( int message )
{
__lower_cc = message;
}

inline int Instrument::get_lower_cc() const
{
return __lower_cc;
}

inline void Instrument::set_higher_cc( int message )
{
__higher_cc = message;
}

inline int Instrument::get_higher_cc() const
{
return __higher_cc;
}

inline InstrumentLayer* Instrument::operator[]( int idx )
{
assert( idx>=0 && idx <MAX_LAYERS );
Expand Down
7 changes: 7 additions & 0 deletions src/core/src/IO/alsa_midi_driver.cpp
Expand Up @@ -250,6 +250,13 @@ void AlsaMidiDriver::midi_action( snd_seq_t *seq_handle )
msg.m_nChannel = ev->data.control.channel;
break;

case SND_SEQ_EVENT_KEYPRESS:
msg.m_type = MidiMessage::POLYPHONIC_KEY_PRESSURE;
msg.m_nData1 = ev->data.note.note;
msg.m_nData2 = ev->data.note.velocity;
msg.m_nChannel = ev->data.control.channel;
break;

case SND_SEQ_EVENT_SYSEX: {
msg.m_type = MidiMessage::SYSEX;
snd_midi_event_t *seq_midi_parser;
Expand Down
7 changes: 7 additions & 0 deletions src/core/src/IO/jack_midi_driver.cpp
Expand Up @@ -117,6 +117,13 @@ JackMidiDriver::JackMidiWrite(jack_nframes_t nframes)
msg.m_nChannel = buffer[0] & 0xF;
handleMidiMessage(msg);
break;
case 0xA: /* aftertouch */
msg.m_type = MidiMessage::POLYPHONIC_KEY_PRESSURE;
msg.m_nData1 = buffer[1];
msg.m_nData2 = buffer[2];
msg.m_nChannel = buffer[0] & 0xF;
handleMidiMessage(msg);
break;
case 0xB: /* control change */
msg.m_type = MidiMessage::CONTROL_CHANGE;
msg.m_nData1 = buffer[1];
Expand Down
53 changes: 47 additions & 6 deletions src/core/src/IO/midi_input.cpp
Expand Up @@ -37,6 +37,7 @@ namespace H2Core
MidiInput::MidiInput( const char* class_name )
: Object( class_name )
, m_bActive( false )
, __hihat_cc_openess ( 127 )
{
//INFOLOG( "INIT" );

Expand Down Expand Up @@ -94,11 +95,14 @@ void MidiInput::handleMidiMessage( const MidiMessage& msg )

case MidiMessage::NOTE_OFF:
INFOLOG("This is a NOTE OFF message.");
handleNoteOffMessage( msg );
handleNoteOffMessage( msg, false );
break;

case MidiMessage::POLYPHONIC_KEY_PRESSURE:
ERRORLOG( "POLYPHONIC_KEY_PRESSURE event not handled yet" );
//ERRORLOG( "POLYPHONIC_KEY_PRESSURE event not handled yet" );
INFOLOG( QString( "[handleMidiMessage] POLYPHONIC_KEY_PRESSURE Parameter: %1, Value: %2")
.arg( msg.m_nData1 ).arg( msg.m_nData2 ) );
handlePolyphonicKeyPressureMessage( msg );
break;

case MidiMessage::CONTROL_CHANGE:
Expand Down Expand Up @@ -177,6 +181,9 @@ void MidiInput::handleControlChangeMessage( const MidiMessage& msg )

aH->handleAction( pAction );

if(msg.m_nData1 == 04)
__hihat_cc_openess = msg.m_nData2;

pEngine->lastMidiEvent = "CC";
pEngine->lastMidiEventParameter = msg.m_nData1;
}
Expand Down Expand Up @@ -205,7 +212,7 @@ void MidiInput::handleNoteOnMessage( const MidiMessage& msg )
float fVelocity = msg.m_nData2 / 127.0;

if ( fVelocity == 0 ) {
handleNoteOffMessage( msg );
handleNoteOffMessage( msg, false );
return;
}

Expand Down Expand Up @@ -251,18 +258,52 @@ void MidiInput::handleNoteOnMessage( const MidiMessage& msg )
nInstrument = MAX_INSTRUMENTS - 1;
}

InstrumentList *instrList = pEngine->getSong()->get_instrument_list();
Instrument *instr = instrList->get( nInstrument );
/*
Only look to change instrument if the
current note is actually of hihat and
hihat openess is outside the instrument selected
*/
if ( instr != NULL &&
instr->is_hihat() &&
( __hihat_cc_openess < instr->get_lower_cc() || __hihat_cc_openess > instr->get_higher_cc() ) )
{
for(int i=0 ; i<=instrList->size() ; i++)
{
Instrument *instr_contestant = instrList->get( i );
if( instr_contestant != NULL &&
instr_contestant->is_hihat() &&
__hihat_cc_openess >= instr_contestant->get_lower_cc() &&
__hihat_cc_openess <= instr_contestant->get_higher_cc() )
{
nInstrument = i;
break;
}
}
}

pEngine->addRealtimeNote( nInstrument, fVelocity, fPan_L, fPan_R, 0.0, false, true, nNote );
}

__noteOnTick = pEngine->__getMidiRealtimeNoteTickPosition();
}

/*
EDrums (at least Roland TD-6V) uses PolyphonicKeyPressure
for cymbal choke.
If the message is 127 (choked) we send a NoteOff
*/
void MidiInput::handlePolyphonicKeyPressureMessage( const MidiMessage& msg )
{
if( msg.m_nData2 == 127 )
handleNoteOffMessage( msg, true );
}


void MidiInput::handleNoteOffMessage( const MidiMessage& msg )
void MidiInput::handleNoteOffMessage( const MidiMessage& msg, bool CymbalChoke )
{
// INFOLOG( "handleNoteOffMessage" );
if ( Preferences::get_instance()->m_bMidiNoteOffIgnore ) {
if ( !CymbalChoke && Preferences::get_instance()->m_bMidiNoteOffIgnore ) {
return;
}

Expand Down
16 changes: 16 additions & 0 deletions src/core/src/basics/instrument.cpp
Expand Up @@ -63,6 +63,9 @@ Instrument::Instrument( const int id, const QString& name, ADSR* adsr )
, __muted( false )
, __mute_group( -1 )
, __queued( 0 )
, __hihat( false )
, __lower_cc( 0 )
, __higher_cc( 127 )
{
if ( __adsr==0 ) __adsr = new ADSR();
for ( int i=0; i<MAX_FX; i++ ) __fx_level[i] = 0.0;
Expand Down Expand Up @@ -92,6 +95,9 @@ Instrument::Instrument( Instrument* other )
, __muted( other->is_muted() )
, __mute_group( other->get_mute_group() )
, __queued( other->is_queued() )
, __hihat( other->is_hihat() )
, __lower_cc( other->get_lower_cc() )
, __higher_cc( other->get_higher_cc() )
{
for ( int i=0; i<MAX_FX; i++ ) __fx_level[i] = other->get_fx_level( i );

Expand Down Expand Up @@ -173,6 +179,9 @@ void Instrument::load_from( Drumkit* drumkit, Instrument* instrument, bool is_li
this->set_midi_out_channel( instrument->get_midi_out_channel() );
this->set_midi_out_note( instrument->get_midi_out_note() );
this->set_stop_notes( instrument->is_stop_notes() );
this->set_hihat( instrument->is_hihat() );
this->set_lower_cc( instrument->get_lower_cc() );
this->set_higher_cc( instrument->get_higher_cc() );
if ( is_live )
AudioEngine::get_instance()->unlock();
}
Expand Down Expand Up @@ -214,6 +223,10 @@ Instrument* Instrument::load_from( XMLNode* node, const QString& dk_path, const
instrument->set_midi_out_channel( node->read_int( "midiOutChannel", -1, true, false ) );
instrument->set_midi_out_note( node->read_int( "midiOutNote", MIDI_MIDDLE_C, true, false ) );
instrument->set_stop_notes( node->read_bool( "isStopNote", true ,false ) );
instrument->set_hihat( node->read_bool( "isHihat", false, true ) );
instrument->set_lower_cc( node->read_int( "lower_cc", 0, true ) );
instrument->set_higher_cc( node->read_int( "higher_cc", 127, true ) );

for ( int i=0; i<MAX_FX; i++ ) {
instrument->set_fx_level( node->read_float( QString( "FX%1Level" ).arg( i+1 ), 0.0 ), i );
}
Expand Down Expand Up @@ -269,6 +282,9 @@ void Instrument::save_to( XMLNode* node )
instrument_node.write_int( "midiOutChannel", __midi_out_channel );
instrument_node.write_int( "midiOutNote", __midi_out_note );
instrument_node.write_bool( "isStopNote", __stop_notes );
instrument_node.write_bool( "isHihat", __hihat );
instrument_node.write_int( "lower_cc", __lower_cc );
instrument_node.write_int( "higher_cc", __higher_cc );
for ( int i=0; i<MAX_FX; i++ ) {
instrument_node.write_float( QString( "FX%1Level" ).arg( i+1 ), __fx_level[i] );
}
Expand Down
3 changes: 3 additions & 0 deletions src/core/src/helpers/legacy.cpp
Expand Up @@ -82,6 +82,9 @@ Drumkit* Legacy::load_drumkit( const QString& dk_path ) {
instrument->set_midi_out_channel( instrument_node.read_int( "midiOutChannel", -1, true, false ) );
instrument->set_midi_out_note( instrument_node.read_int( "midiOutNote", MIDI_MIDDLE_C, true, false ) );
instrument->set_stop_notes( instrument_node.read_bool( "isStopNote", true ,false ) );
instrument->set_hihat( instrument_node.read_bool( "isHihat", false, true ) );
instrument->set_lower_cc( instrument_node.read_int( "lower_cc", 0, true ) );
instrument->set_higher_cc( instrument_node.read_int( "higher_cc", 127, true ) );
for ( int i=0; i<MAX_FX; i++ ) {
instrument->set_fx_level( instrument_node.read_float( QString( "FX%1Level" ).arg( i+1 ), 0.0 ), i );
}
Expand Down

0 comments on commit 15b5808

Please sign in to comment.