diff --git a/.gitignore b/.gitignore
index 3cf3ecc3f6..8e66b1f076 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,5 @@ moc_*.cc
/libs/hydrogen/include/hydrogen/config.h
/cmake_opts
/hydrogen
+*.cbp
+*.layout
diff --git a/data/img/gray/instrumentEditor/instrumentTab_new.png b/data/img/gray/instrumentEditor/instrumentTab_new.png
new file mode 100644
index 0000000000..b7edbad710
Binary files /dev/null and b/data/img/gray/instrumentEditor/instrumentTab_new.png differ
diff --git a/data/xsd/drumkit.xsd b/data/xsd/drumkit.xsd
index f62038bfd4..94786ac9f5 100644
--- a/data/xsd/drumkit.xsd
+++ b/data/xsd/drumkit.xsd
@@ -61,6 +61,9 @@
+
+
+
diff --git a/src/core/include/hydrogen/IO/MidiInput.h b/src/core/include/hydrogen/IO/MidiInput.h
index 0f33ba064c..edfc5635bb 100644
--- a/src/core/include/hydrogen/IO/MidiInput.h
+++ b/src/core/include/hydrogen/IO/MidiInput.h
@@ -51,12 +51,13 @@ 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:
@@ -64,6 +65,8 @@ class MidiInput : public virtual Object
unsigned long __noteOffTick;
unsigned long computeDeltaNoteOnOfftime();
+ int __hihat_cc_openess;
+
};
diff --git a/src/core/include/hydrogen/basics/instrument.h b/src/core/include/hydrogen/basics/instrument.h
index 5a6b5150c3..f09e7b8919 100644
--- a/src/core/include/hydrogen/basics/instrument.h
+++ b/src/core/include/hydrogen/basics/instrument.h
@@ -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
@@ -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
@@ -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 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;
diff --git a/src/core/src/IO/jack_midi_driver.cpp b/src/core/src/IO/jack_midi_driver.cpp
index 364a366faf..4cb5af7013 100644
--- a/src/core/src/IO/jack_midi_driver.cpp
+++ b/src/core/src/IO/jack_midi_driver.cpp
@@ -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];
diff --git a/src/core/src/IO/midi_input.cpp b/src/core/src/IO/midi_input.cpp
index 6dc6d8d94d..5690a0729e 100644
--- a/src/core/src/IO/midi_input.cpp
+++ b/src/core/src/IO/midi_input.cpp
@@ -37,6 +37,7 @@ namespace H2Core
MidiInput::MidiInput( const char* class_name )
: Object( class_name )
, m_bActive( false )
+ , __hihat_cc_openess ( 127 )
{
//INFOLOG( "INIT" );
@@ -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:
@@ -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;
}
@@ -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;
}
@@ -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;
}
diff --git a/src/core/src/basics/instrument.cpp b/src/core/src/basics/instrument.cpp
index acbed8c7e8..a0aee7d4f5 100644
--- a/src/core/src/basics/instrument.cpp
+++ b/src/core/src/basics/instrument.cpp
@@ -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; iis_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; iget_fx_level( i );
@@ -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();
}
@@ -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; iset_fx_level( node->read_float( QString( "FX%1Level" ).arg( i+1 ), 0.0 ), i );
}
@@ -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; iset_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; iset_fx_level( instrument_node.read_float( QString( "FX%1Level" ).arg( i+1 ), 0.0 ), i );
}
diff --git a/src/gui/src/InstrumentEditor/InstrumentEditor.cpp b/src/gui/src/InstrumentEditor/InstrumentEditor.cpp
index 8c20450432..e32e421dc8 100644
--- a/src/gui/src/InstrumentEditor/InstrumentEditor.cpp
+++ b/src/gui/src/InstrumentEditor/InstrumentEditor.cpp
@@ -95,16 +95,16 @@ InstrumentEditor::InstrumentEditor( QWidget* pParent )
// Instrument properties
m_pInstrumentProp = new PixmapWidget( this );
m_pInstrumentProp->move(0, 31);
- m_pInstrumentProp->setPixmap( "/instrumentEditor/instrumentTab.png" );
+ m_pInstrumentProp->setPixmap( "/instrumentEditor/instrumentTab_new.png" );
m_pNameLbl = new ClickableLabel( m_pInstrumentProp );
m_pNameLbl->setGeometry( 8, 5, 275, 28 );
-
+
/////////////
//Midi Out
-
+
m_pMidiOutChannelLCD = new LCDDisplay( m_pInstrumentProp, LCDDigit::SMALL_BLUE, 4 );
- m_pMidiOutChannelLCD->move( 67, 243 );
+ m_pMidiOutChannelLCD->move( 67, 261 );
m_pAddMidiOutChannelBtn = new Button(
m_pInstrumentProp,
@@ -114,7 +114,7 @@ InstrumentEditor::InstrumentEditor( QWidget* pParent )
QSize( 16, 8 )
);
- m_pAddMidiOutChannelBtn->move( 109, 243 );
+ m_pAddMidiOutChannelBtn->move( 109, 260 );
connect( m_pAddMidiOutChannelBtn, SIGNAL( clicked(Button*) ), this, SLOT( midiOutChannelBtnClicked(Button*) ) );
@@ -125,12 +125,12 @@ InstrumentEditor::InstrumentEditor( QWidget* pParent )
"/lcd/LCDSpinBox_down_over.png",
QSize(16,8)
);
- m_pDelMidiOutChannelBtn->move( 109, 251 );
+ m_pDelMidiOutChannelBtn->move( 109, 269 );
connect( m_pDelMidiOutChannelBtn, SIGNAL( clicked(Button*) ), this, SLOT( midiOutChannelBtnClicked(Button*) ) );
-
+
///
m_pMidiOutNoteLCD = new LCDDisplay( m_pInstrumentProp, LCDDigit::SMALL_BLUE, 4 );
- m_pMidiOutNoteLCD->move( 160, 243 );
+ m_pMidiOutNoteLCD->move( 160, 261 );
m_pAddMidiOutNoteBtn = new Button(
m_pInstrumentProp,
@@ -140,7 +140,7 @@ InstrumentEditor::InstrumentEditor( QWidget* pParent )
QSize( 16, 8 )
);
- m_pAddMidiOutNoteBtn->move( 202, 243 );
+ m_pAddMidiOutNoteBtn->move( 202, 260 );
connect( m_pAddMidiOutNoteBtn, SIGNAL( clicked(Button*) ), this, SLOT( midiOutNoteBtnClicked(Button*) ) );
@@ -151,9 +151,9 @@ InstrumentEditor::InstrumentEditor( QWidget* pParent )
"/lcd/LCDSpinBox_down_over.png",
QSize(16,8)
);
- m_pDelMidiOutNoteBtn->move( 202, 251 );
+ m_pDelMidiOutNoteBtn->move( 202, 269 );
connect( m_pDelMidiOutNoteBtn, SIGNAL( clicked(Button*) ), this, SLOT( midiOutNoteBtnClicked(Button*) ) );
-
+
/////////////
QFont boldFont;
@@ -162,7 +162,7 @@ InstrumentEditor::InstrumentEditor( QWidget* pParent )
connect( m_pNameLbl, SIGNAL( labelClicked(ClickableLabel*) ), this, SLOT( labelClicked(ClickableLabel*) ) );
m_pRandomPitchRotary = new Rotary( m_pInstrumentProp, Rotary::TYPE_NORMAL, trUtf8( "Random pitch factor" ), false, true );
- m_pRandomPitchRotary->move( 117, 192 );
+ m_pRandomPitchRotary->move( 117, 210 );
connect( m_pRandomPitchRotary, SIGNAL( valueChanged(Rotary*) ), this, SLOT( rotaryChanged(Rotary*) ) );
// Filter
@@ -181,9 +181,9 @@ InstrumentEditor::InstrumentEditor( QWidget* pParent )
m_pResonanceRotary = new Rotary( m_pInstrumentProp, Rotary::TYPE_NORMAL, trUtf8( "Filter resonance" ), false, true );
connect( m_pResonanceRotary, SIGNAL( valueChanged(Rotary*) ), this, SLOT( rotaryChanged(Rotary*) ) );
- m_pFilterBypassBtn->move( 70, 152 );
- m_pCutoffRotary->move( 117, 146 );
- m_pResonanceRotary->move( 170, 146 );
+ m_pFilterBypassBtn->move( 70, 170 );
+ m_pCutoffRotary->move( 117, 164 );
+ m_pResonanceRotary->move( 170, 164 );
//~ Filter
// ADSR
@@ -234,11 +234,70 @@ InstrumentEditor::InstrumentEditor( QWidget* pParent )
m_pDelMuteGroupBtn->move( 202, 113 );
connect( m_pDelMuteGroupBtn, SIGNAL( clicked(Button*) ), this, SLOT( muteGroupBtnClicked(Button*) ) );
- m_pIsStopNoteCheckBox = new QCheckBox ( trUtf8( "Auto-Stop-Note" ), m_pInstrumentProp );
- m_pIsStopNoteCheckBox->move( 15, 300 );
+ m_pIsStopNoteCheckBox = new QCheckBox ( trUtf8( "" ), m_pInstrumentProp );
+ m_pIsStopNoteCheckBox->move( 63, 138 );
m_pIsStopNoteCheckBox->setToolTip( trUtf8( "Stop the current playing instrument-note before trigger the next note sample." ) );
connect( m_pIsStopNoteCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( onIsStopNoteCheckBoxClicked( bool ) ) );
+ //////////////////////////
+ // HiHat setup
+
+ m_pIsHihat = new QCheckBox ( trUtf8( "" ), m_pInstrumentProp );
+ m_pIsHihat->move( 63, 304 );
+ m_pIsHihat->setToolTip( trUtf8( "Set the instrument as part of a hihat set." ) );
+ connect( m_pIsHihat, SIGNAL( toggled( bool ) ), this, SLOT( pIsHihatCheckBoxClicked( bool ) ) );
+
+
+ m_pHihatMinRangeLCD = new LCDDisplay( m_pInstrumentProp, LCDDigit::SMALL_BLUE, 4 );
+ m_pHihatMinRangeLCD->move( 67, 320 );
+
+ m_pAddHihatMinRangeBtn = new Button(
+ m_pInstrumentProp,
+ "/lcd/LCDSpinBox_up_on.png",
+ "/lcd/LCDSpinBox_up_off.png",
+ "/lcd/LCDSpinBox_up_over.png",
+ QSize( 16, 8 )
+ );
+ m_pAddHihatMinRangeBtn->move( 109, 319 );
+ connect( m_pAddHihatMinRangeBtn, SIGNAL( clicked(Button*) ), this, SLOT( hihatMinRangeBtnClicked(Button*) ) );
+
+ m_pDelHihatMinRangeBtn = new Button(
+ m_pInstrumentProp,
+ "/lcd/LCDSpinBox_down_on.png",
+ "/lcd/LCDSpinBox_down_off.png",
+ "/lcd/LCDSpinBox_down_over.png",
+ QSize(16,8)
+ );
+ m_pDelHihatMinRangeBtn->move( 109, 328 );
+ connect( m_pDelHihatMinRangeBtn, SIGNAL( clicked(Button*) ), this, SLOT( hihatMinRangeBtnClicked(Button*) ) );
+
+
+ m_pHihatMaxRangeLCD = new LCDDisplay( m_pInstrumentProp, LCDDigit::SMALL_BLUE, 4 );
+ m_pHihatMaxRangeLCD->move( 160, 320 );
+
+ m_pAddHihatMaxRangeBtn = new Button(
+ m_pInstrumentProp,
+ "/lcd/LCDSpinBox_up_on.png",
+ "/lcd/LCDSpinBox_up_off.png",
+ "/lcd/LCDSpinBox_up_over.png",
+ QSize( 16, 8 )
+ );
+ m_pAddHihatMaxRangeBtn->move( 202, 319 );
+ connect( m_pAddHihatMaxRangeBtn, SIGNAL( clicked(Button*) ), this, SLOT( hihatMaxRangeBtnClicked(Button*) ) );
+
+ m_pDelHihatMaxRangeBtn = new Button(
+ m_pInstrumentProp,
+ "/lcd/LCDSpinBox_down_on.png",
+ "/lcd/LCDSpinBox_down_off.png",
+ "/lcd/LCDSpinBox_down_over.png",
+ QSize(16,8)
+ );
+ m_pDelHihatMaxRangeBtn->move( 202, 328 );
+ connect( m_pDelHihatMaxRangeBtn, SIGNAL( clicked(Button*) ), this, SLOT( hihatMaxRangeBtnClicked(Button*) ) );
+
+ //
+
+
//~ Instrument properties
@@ -255,7 +314,7 @@ InstrumentEditor::InstrumentEditor( QWidget* pParent )
// Layer preview
m_pLayerPreview = new LayerPreview( NULL );
-
+
m_pLayerScrollArea = new QScrollArea( m_pLayerProp);
m_pLayerScrollArea->setFrameShape( QFrame::NoFrame );
m_pLayerScrollArea->move( 6, 4 );
@@ -421,22 +480,29 @@ void InstrumentEditor::selectedInstrumentChangedEvent()
if (m_pInstrument->get_mute_group() == -1 ) {
sMuteGroup = "Off";
}
- m_pMuteGroupLCD->setText( sMuteGroup );
-
+ m_pMuteGroupLCD->setText( sMuteGroup );
+
// midi out
QString sMidiOutChannel = QString("%1").arg( m_pInstrument->get_midi_out_channel()+1);
if (m_pInstrument->get_midi_out_channel() == -1 ) {
sMidiOutChannel = "Off";
}
m_pMidiOutChannelLCD->setText( sMidiOutChannel );
-
+
+ // hihat
+ m_pIsHihat->setChecked( m_pInstrument->is_hihat() );
+ QString sHiHatMinRange = QString("%1").arg( m_pInstrument->get_lower_cc() );
+ m_pHihatMinRangeLCD->setText( sHiHatMinRange );
+ QString sHiHatMaxRange = QString("%1").arg( m_pInstrument->get_higher_cc() );
+ m_pHihatMaxRangeLCD->setText( sHiHatMaxRange );
+
//Convert note id into notation
{
int note = m_pInstrument->get_midi_out_note();
int octave = (note / 12) - 2;
const char *noteStrs[12] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };
QString sMidiOutNote = QString(noteStrs[note % 12]) + QString::number(octave);
- m_pMidiOutNoteLCD->setText( sMidiOutNote );
+ m_pMidiOutNoteLCD->setText( sMidiOutNote );
}
// select the last valid layer
@@ -593,7 +659,7 @@ void InstrumentEditor::buttonClicked( Button* pButton )
HydrogenApp::get_instance()->showSampleEditor( name, m_nSelectedLayer );
}
}
-
+
}
else {
ERRORLOG( "[buttonClicked] unhandled button" );
@@ -620,7 +686,7 @@ void InstrumentEditor::loadLayer()
if ( filename[2].isEmpty() ) return;
- bool fnc = false;
+ bool fnc = false;
if ( filename[0] == "true" ){
fnc = true;
}
@@ -630,36 +696,36 @@ void InstrumentEditor::loadLayer()
int selectedLayer = m_nSelectedLayer;
int firstSelection = selectedLayer;
-
-
+
+
if (filename.size() > 2) {
-
- for(int i=2;i < filename.size();++i)
+
+ for(int i=2;i < filename.size();++i)
{
selectedLayer = m_nSelectedLayer + i - 2;
if( ( i-2 >= MAX_LAYERS ) || ( selectedLayer + 1 > MAX_LAYERS ) ) break;
Sample *newSample = Sample::load( filename[i] );
-
+
H2Core::Instrument *pInstr = NULL;
-
+
AudioEngine::get_instance()->lock( RIGHT_HERE );
Song *song = engine->getSong();
InstrumentList *instrList = song->get_instrument_list();
pInstr = instrList->get( engine->getSelectedInstrumentNumber() );
-
- /*
- if we're using multiple layers, we start inserting the first layer
+
+ /*
+ if we're using multiple layers, we start inserting the first layer
at m_nSelectedLayer and the next layer at m_nSelectedLayer+1
*/
-
+
H2Core::InstrumentLayer *pLayer = pInstr->get_layer( selectedLayer );
if (pLayer != NULL) {
// delete old sample
Sample *oldSample = pLayer->get_sample();
delete oldSample;
-
+
// insert new sample from newInstrument
pLayer->set_sample( newSample );
}
@@ -667,20 +733,20 @@ void InstrumentEditor::loadLayer()
pLayer = new H2Core::InstrumentLayer(newSample);
pInstr->set_layer( pLayer, selectedLayer );
}
-
+
if ( fnc ){
QString newFilename = filename[i].section( '/', -1 );
newFilename.replace( "." + newFilename.section( '.', -1 ), "");
m_pInstrument->set_name( newFilename );
}
-
+
//set automatic velocity
if ( filename[1] == "true" ){
setAutoVelocity();
}
-
+
//pInstr->set_drumkit_name( "" ); // external sample, no drumkit info
-
+
AudioEngine::get_instance()->unlock();
}
@@ -877,13 +943,13 @@ void InstrumentEditor::midiOutNoteBtnClicked(Button *pRef)
);
if( !newSample ){
continue;
- }
+ }
delete pSample;
// insert new sample from newInstrument
AudioEngine::get_instance()->lock( RIGHT_HERE );
pLayer->set_sample( newSample );
AudioEngine::get_instance()->unlock();
-
+
}
}
}
@@ -893,3 +959,35 @@ void InstrumentEditor::midiOutNoteBtnClicked(Button *pRef)
}
}
+
+void InstrumentEditor::pIsHihatCheckBoxClicked( bool on )
+{
+ assert( m_pInstrument );
+
+ m_pInstrument->set_hihat( on );
+ selectedInstrumentChangedEvent(); // force an update
+}
+
+void InstrumentEditor::hihatMinRangeBtnClicked(Button *pRef)
+{
+ assert( m_pInstrument );
+
+ if ( pRef == m_pAddHihatMinRangeBtn && m_pInstrument->get_lower_cc() < 127 )
+ m_pInstrument->set_lower_cc( m_pInstrument->get_lower_cc() + 1 );
+ else if ( pRef == m_pDelHihatMinRangeBtn && m_pInstrument->get_lower_cc() > 0 )
+ m_pInstrument->set_lower_cc( m_pInstrument->get_lower_cc() - 1 );
+
+ selectedInstrumentChangedEvent(); // force an update
+}
+
+void InstrumentEditor::hihatMaxRangeBtnClicked(Button *pRef)
+{
+ assert( m_pInstrument );
+
+ if ( pRef == m_pAddHihatMaxRangeBtn && m_pInstrument->get_higher_cc() < 127 )
+ m_pInstrument->set_higher_cc( m_pInstrument->get_higher_cc() + 1);
+ else if ( pRef == m_pDelHihatMaxRangeBtn && m_pInstrument->get_higher_cc() > 0 )
+ m_pInstrument->set_higher_cc( m_pInstrument->get_higher_cc() - 1);
+
+ selectedInstrumentChangedEvent(); // force an update
+}
diff --git a/src/gui/src/InstrumentEditor/InstrumentEditor.h b/src/gui/src/InstrumentEditor/InstrumentEditor.h
index 3f0f31a55b..50edef746c 100644
--- a/src/gui/src/InstrumentEditor/InstrumentEditor.h
+++ b/src/gui/src/InstrumentEditor/InstrumentEditor.h
@@ -73,6 +73,10 @@ class InstrumentEditor : public QWidget, public H2Core::Object, public EventList
void midiOutChannelBtnClicked(Button *pRef);
void midiOutNoteBtnClicked(Button *pRef);
+ void pIsHihatCheckBoxClicked( bool on);
+ void hihatMinRangeBtnClicked(Button *pRef);
+ void hihatMaxRangeBtnClicked(Button *pRef);
+
private:
H2Core::Instrument *m_pInstrument;
int m_nSelectedLayer;
@@ -107,15 +111,27 @@ class InstrumentEditor : public QWidget, public H2Core::Object, public EventList
LCDDisplay *m_pMuteGroupLCD;
Button *m_pAddMuteGroupBtn;
Button *m_pDelMuteGroupBtn;
-
+
// Instrument midi out
LCDDisplay *m_pMidiOutChannelLCD;
Button *m_pAddMidiOutChannelBtn;
Button *m_pDelMidiOutChannelBtn;
-
+
LCDDisplay *m_pMidiOutNoteLCD;
Button *m_pAddMidiOutNoteBtn;
- Button *m_pDelMidiOutNoteBtn;
+ Button *m_pDelMidiOutNoteBtn;
+
+ // Instrument hihat
+
+ QCheckBox *m_pIsHihat;
+
+ LCDDisplay *m_pHihatMinRangeLCD;
+ Button *m_pAddHihatMinRangeBtn;
+ Button *m_pDelHihatMinRangeBtn;
+
+ LCDDisplay *m_pHihatMaxRangeLCD;
+ Button *m_pAddHihatMaxRangeBtn;
+ Button *m_pDelHihatMaxRangeBtn;
//~ Instrument properties
@@ -123,7 +139,7 @@ class InstrumentEditor : public QWidget, public H2Core::Object, public EventList
// Layer properties
LayerPreview *m_pLayerPreview;
QScrollArea *m_pLayerScrollArea;
-
+
PixmapWidget *m_pLayerProp;
Rotary *m_pLayerGainRotary;
diff --git a/src/gui/src/widgets/Button.cpp b/src/gui/src/widgets/Button.cpp
index eb65446ae0..c20611d61b 100644
--- a/src/gui/src/widgets/Button.cpp
+++ b/src/gui/src/widgets/Button.cpp
@@ -66,6 +66,10 @@ Button::Button( QWidget * pParent, const QString& sOnImage, const QString& sOffI
}
this->setStyleSheet("font-size: 9px; font-weight: bold;");
+
+ m_timerTimeout = 0;
+ m_timer = new QTimer(this);
+ connect(m_timer, SIGNAL(timeout()), this, SLOT(buttonPressed_timer_timeout()));
}
@@ -126,7 +130,14 @@ void Button::mousePressEvent(QMouseEvent*ev) {
m_bPressed = true;
update();
+
emit mousePress(this);
+
+ if ( ev->button() == Qt::LeftButton )
+ {
+ m_timerTimeout = 2000;
+ buttonPressed_timer_timeout();
+ }
}
@@ -136,12 +147,20 @@ void Button::mouseReleaseEvent(QMouseEvent* ev)
setPressed( false );
if (ev->button() == Qt::LeftButton) {
- emit clicked(this);
+ m_timer->stop();
}
else if (ev->button() == Qt::RightButton) {
emit rightClicked(this);
}
+}
+
+void Button::buttonPressed_timer_timeout()
+{
+ emit clicked(this);
+ if(m_timerTimeout > 50)
+ m_timerTimeout = m_timerTimeout / 2;
+ m_timer->start(m_timerTimeout);
}
void Button::setFontSize(int size)
diff --git a/src/gui/src/widgets/Button.h b/src/gui/src/widgets/Button.h
index 1452fbd8cf..4f28804527 100644
--- a/src/gui/src/widgets/Button.h
+++ b/src/gui/src/widgets/Button.h
@@ -64,6 +64,9 @@ class Button : public QWidget, public H2Core::Object, public MidiLearnable
void rightClicked(Button *pBtn);
void mousePress(Button *pBtn);
+ protected slots:
+ void buttonPressed_timer_timeout();
+
protected:
bool m_bPressed;
@@ -84,6 +87,9 @@ class Button : public QWidget, public H2Core::Object, public MidiLearnable
void leaveEvent(QEvent *ev);
void paintEvent( QPaintEvent* ev);
+ QTimer *m_timer;
+ int m_timerTimeout;
+
bool loadImage( const QString& sFilename, QPixmap& pixmap );
};