diff --git a/include/EnvelopeAndLfoView.h b/include/EnvelopeAndLfoView.h index dec4a5bb8..8df71b0ed 100644 --- a/include/EnvelopeAndLfoView.h +++ b/include/EnvelopeAndLfoView.h @@ -23,8 +23,8 @@ * */ -#ifndef _ENVELOPE_AND_LFO_VIEW_H -#define _ENVELOPE_AND_LFO_VIEW_H +#ifndef ENVELOPE_AND_LFO_VIEW_H +#define ENVELOPE_AND_LFO_VIEW_H #include diff --git a/include/Piano.h b/include/Piano.h index b1487095f..8e86622fc 100644 --- a/include/Piano.h +++ b/include/Piano.h @@ -22,8 +22,8 @@ * */ -#ifndef _PIANO_H -#define _PIANO_H +#ifndef PIANO_H +#define PIANO_H #include "note.h" #include "Model.h" @@ -50,7 +50,7 @@ public: return m_pressedKeys[key]; } - void handleKeyPress( int key, int midiVelocity = MidiDefaultVelocity ); + void handleKeyPress( int key, int midiVelocity = -1 ); void handleKeyRelease( int key ); InstrumentTrack* instrumentTrack() const diff --git a/plugins/opl2/opl2instrument.cpp b/plugins/opl2/opl2instrument.cpp index 26c3ae10a..4704f0147 100644 --- a/plugins/opl2/opl2instrument.cpp +++ b/plugins/opl2/opl2instrument.cpp @@ -22,7 +22,7 @@ * */ -// TODO: +// TODO: // - Better voice allocation: long releases get cut short :( // - .sbi (or similar) file loading into models // - RT safety = get rid of mutex = make emulator code thread-safe @@ -36,9 +36,9 @@ // - SBI file import? // - Envelope times in ms for UI: t[0] = 0, t[n] = ( 1<write(0x40+adlib_opadd[voice], + theEmulator->write(0x40+adlib_opadd[voice], ( (int)op1_scale_mdl.value() & 0x03 << 6) + ( vel_adjusted & 0x3f ) ); - + vel_adjusted = 63 - ( op2_lvl_mdl.value() * vel/127.0 ); // vel_adjusted = 63 - op2_lvl_mdl.value(); - theEmulator->write(0x43+adlib_opadd[voice], + theEmulator->write(0x43+adlib_opadd[voice], ( (int)op2_scale_mdl.value() & 0x03 << 6) + ( vel_adjusted & 0x3f ) ); } @@ -293,10 +293,10 @@ bool opl2instrument::handleMidiEvent( const MidiEvent& event, const MidiTime& ti // to get us in line with MIDI(?) key = event.key() +12; vel = event.velocity(); - + voice = popVoice(); if( voice != OPL2_NO_VOICE ) { - // Turn voice on, NB! the frequencies are straight by voice number, + // Turn voice on, NB! the frequencies are straight by voice number, // not by the adlib_opadd table! theEmulator->write(0xA0+voice, fnums[key] & 0xff); theEmulator->write(0xB0+voice, 32 + ((fnums[key] & 0x1f00) >> 8) ); @@ -306,7 +306,7 @@ bool opl2instrument::handleMidiEvent( const MidiEvent& event, const MidiTime& ti } break; case MidiNoteOff: - key = event.key() +12; + key = event.key() +12; for(voice=0; voice<9; ++voice) { if( voiceNote[voice] == key ) { theEmulator->write(0xA0+voice, fnums[key] & 0xff); @@ -331,12 +331,12 @@ bool opl2instrument::handleMidiEvent( const MidiEvent& event, const MidiTime& ti break; case MidiPitchBend: // Update fnumber table - // Pitchbend should be in the range 0...16383 but the new range knob gets it wrong. + // Pitchbend should be in the range 0...16383 but the new range knob gets it wrong. // tmp_pb = (2*BEND_CENTS)*((float)event.m_data.m_param[0]/16383)-BEND_CENTS; // Something like 100 cents = 8192, but offset by 8192 so the +/-100 cents range goes from 0...16383? tmp_pb = ( event.pitchBend()-8192 ) * pitchBendRange / 8192; - + if( tmp_pb != pitchbend ) { pitchbend = tmp_pb; tuneEqual(69, 440.0); @@ -349,7 +349,7 @@ bool opl2instrument::handleMidiEvent( const MidiEvent& event, const MidiTime& ti } } break; - case MidiControlChange: + case MidiControlChange: switch (event.controllerNumber()) { case MidiControllerRegisteredParameterNumberLSB: RPNfine = event.controllerValue(); @@ -385,14 +385,14 @@ PluginView * opl2instrument::instantiateView( QWidget * _parent ) } -void opl2instrument::play( sampleFrame * _working_buffer ) +void opl2instrument::play( sampleFrame * _working_buffer ) { emulatorMutex.lock(); theEmulator->update(renderbuffer, frameCount); for( fpp_t frame = 0; frame < frameCount; ++frame ) { - sample_t s = float(renderbuffer[frame])/32768.0; + sample_t s = float(renderbuffer[frame]) / 8192.0; for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch ) { _working_buffer[frame][ch] = s; @@ -406,7 +406,7 @@ void opl2instrument::play( sampleFrame * _working_buffer ) } -void opl2instrument::saveSettings( QDomDocument & _doc, QDomElement & _this ) +void opl2instrument::saveSettings( QDomDocument & _doc, QDomElement & _this ) { op1_a_mdl.saveSettings( _doc, _this, "op1_a" ); op1_d_mdl.saveSettings( _doc, _this, "op1_d" ); @@ -577,11 +577,11 @@ opl2instrumentView::opl2instrumentView( Instrument * _instrument, QWidget * _parent ) : InstrumentView( _instrument, _parent ) { - /* Unnecessary? + /* Unnecessary? m_patch = new LcdSpinBox( 3, this , "PRESET"); m_patch->setLabel( "PRESET" ); m_patch->move( 100, 1 ); - m_patch->setEnabled( true ); + m_patch->setEnabled( true ); */ #define KNOB_GEN(knobname, hinttext, hintunit,xpos,ypos) \ @@ -608,7 +608,7 @@ opl2instrumentView::opl2instrumentView( Instrument * _instrument, toolTip::add( buttname, tr( tooltip ) );\ buttname->move( xpos, ypos );\ buttgroup->addButton(buttname); - + // OP1 knobs & buttons... KNOB_GEN(op1_a_kn, "Attack", "", 6, 48); diff --git a/src/core/Piano.cpp b/src/core/Piano.cpp index 584362f46..93fa34869 100644 --- a/src/core/Piano.cpp +++ b/src/core/Piano.cpp @@ -3,7 +3,7 @@ * for testing + according model class * * Copyright (c) 2004-2014 Tobias Doerffel - * + * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * * This program is free software; you can redistribute it and/or @@ -31,7 +31,7 @@ * \mainpage Instrument plugin keyboard display classes * * \section introduction Introduction - * + * * \todo fill this out * \todo write isWhite inline function and replace throughout */ @@ -95,6 +95,10 @@ void Piano::setKeyState( int key, bool state ) */ void Piano::handleKeyPress( int key, int midiVelocity ) { + if( midiVelocity == -1 ) + { + midiVelocity = m_instrumentTrack->midiPort()->baseVelocity(); + } if( isValidKey( key ) ) { m_midiEvProc->processInEvent( MidiEvent( MidiNoteOn, 0, key, midiVelocity ) ); diff --git a/src/gui/PianoView.cpp b/src/gui/PianoView.cpp index ce945ec5f..af4b07339 100644 --- a/src/gui/PianoView.cpp +++ b/src/gui/PianoView.cpp @@ -3,7 +3,7 @@ * for testing + according model class * * Copyright (c) 2004-2014 Tobias Doerffel - * + * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * * This program is free software; you can redistribute it and/or @@ -31,7 +31,7 @@ * \mainpage Instrument plugin keyboard display classes * * \section introduction Introduction - * + * * \todo fill this out * \todo write isWhite inline function and replace throughout */ @@ -160,7 +160,7 @@ PianoView::~PianoView() -/*! \brief Map a keyboard key being pressed to a note in our keyboard view +/*! \brief Map a keyboard key being pressed to a note in our keyboard view * * \param _k The keyboard scan code of the key being pressed. * \todo check the scan codes for ',' = c, 'L' = c#, '.' = d, ':' = d#, @@ -255,7 +255,7 @@ int PianoView::getKeyFromKeyEvent( QKeyEvent * _ke ) case 19: return 27; // 0 = d'# case 33: return 28; // P = e' case 34: return 29; // [ - case 21: return 30; // = + case 21: return 30; // = case 35: return 31; // ] } #endif @@ -459,7 +459,7 @@ void PianoView::mousePressEvent( QMouseEvent * _me ) ( ( KEY_ORDER[key_num % KeysPerOctave] == Piano::WhiteKey ) ? PW_WHITE_KEY_HEIGHT : PW_BLACK_KEY_HEIGHT ) * - (float) MidiDefaultVelocity ); + (float) m_piano->instrumentTrack()->midiPort()->baseVelocity() ); if( y_diff < 0 ) { velocity = 0; @@ -469,7 +469,7 @@ void PianoView::mousePressEvent( QMouseEvent * _me ) Piano::WhiteKey ) ? PW_WHITE_KEY_HEIGHT : PW_BLACK_KEY_HEIGHT ) ) { - velocity = MidiDefaultVelocity; + velocity = m_piano->instrumentTrack()->midiPort()->baseVelocity(); } // set note on m_piano->midiEventProcessor()->processInEvent( MidiEvent( MidiNoteOn, 0, key_num, velocity ) ); @@ -557,7 +557,7 @@ void PianoView::mouseMoveEvent( QMouseEvent * _me ) int velocity = (int)( (float) y_diff / ( ( KEY_ORDER[key_num % KeysPerOctave] == Piano::WhiteKey ) ? PW_WHITE_KEY_HEIGHT : PW_BLACK_KEY_HEIGHT ) * - (float) MidiDefaultVelocity ); + (float) m_piano->instrumentTrack()->midiPort()->baseVelocity() ); // maybe the user moved the mouse-cursor above or under the // piano-widget while holding left button so check that and // correct volume if necessary @@ -569,7 +569,7 @@ void PianoView::mouseMoveEvent( QMouseEvent * _me ) ( ( KEY_ORDER[key_num % KeysPerOctave] == Piano::WhiteKey ) ? PW_WHITE_KEY_HEIGHT : PW_BLACK_KEY_HEIGHT ) ) { - velocity = MidiDefaultVelocity; + velocity = m_piano->instrumentTrack()->midiPort()->baseVelocity(); } // is the calculated key different from current key? (could be the diff --git a/src/gui/widgets/EnvelopeAndLfoView.cpp b/src/gui/widgets/EnvelopeAndLfoView.cpp index 712f48ac5..034e00d76 100644 --- a/src/gui/widgets/EnvelopeAndLfoView.cpp +++ b/src/gui/widgets/EnvelopeAndLfoView.cpp @@ -62,8 +62,7 @@ const int SUSTAIN_KNOB_X = DECAY_KNOB_X+KNOB_X_SPACING; const int RELEASE_KNOB_X = SUSTAIN_KNOB_X+KNOB_X_SPACING; const int AMOUNT_KNOB_X = RELEASE_KNOB_X+KNOB_X_SPACING; -const float TIME_UNIT_WIDTH = 24.0; - +const int TIME_UNIT_WIDTH = 40; const int LFO_GRAPH_X = 6; const int LFO_GRAPH_Y = ENV_KNOBS_LBL_Y+14; @@ -425,48 +424,56 @@ void EnvelopeAndLfoView::paintEvent( QPaintEvent * ) const int y_base = ENV_GRAPH_Y + s_envGraph->height() - 3; const int avail_height = s_envGraph->height() - 6; - int x1 = ENV_GRAPH_X + 2 + static_cast( m_predelayKnob->value() * - TIME_UNIT_WIDTH ); - int x2 = x1 + static_cast( m_attackKnob->value() * - TIME_UNIT_WIDTH ); + int x1 = static_cast( m_predelayKnob->value() * TIME_UNIT_WIDTH ); + int x2 = x1 + static_cast( m_attackKnob->value() * TIME_UNIT_WIDTH ); + int x3 = x2 + static_cast( m_holdKnob->value() * TIME_UNIT_WIDTH ); + int x4 = x3 + static_cast( ( m_decayKnob->value() * + ( 1 - m_sustainKnob->value() ) ) * TIME_UNIT_WIDTH ); + int x5 = x4 + static_cast( m_releaseKnob->value() * TIME_UNIT_WIDTH ); + + if( x5 > 174 ) + { + x1 = ( x1 * 174 ) / x5; + x2 = ( x2 * 174 ) / x5; + x3 = ( x3 * 174 ) / x5; + x4 = ( x4 * 174 ) / x5; + x5 = ( x5 * 174 ) / x5; + } + x1 += ENV_GRAPH_X + 2; + x2 += ENV_GRAPH_X + 2; + x3 += ENV_GRAPH_X + 2; + x4 += ENV_GRAPH_X + 2; + x5 += ENV_GRAPH_X + 2; p.drawLine( x1, y_base, x2, y_base - avail_height ); p.fillRect( x1 - 1, y_base - 2, 4, 4, end_points_bg_color ); p.fillRect( x1, y_base - 1, 2, 2, end_points_color ); - x1 = x2; - x2 = x1 + static_cast( m_holdKnob->value() * TIME_UNIT_WIDTH ); - p.drawLine( x1, y_base - avail_height, x2, y_base - avail_height ); - p.fillRect( x1 - 1, y_base - 2 - avail_height, 4, 4, + p.drawLine( x2, y_base - avail_height, x3, y_base - avail_height ); + p.fillRect( x2 - 1, y_base - 2 - avail_height, 4, 4, end_points_bg_color ); - p.fillRect( x1, y_base - 1 - avail_height, 2, 2, end_points_color ); - x1 = x2; - x2 = x1 + static_cast( ( m_decayKnob->value() * - ( 1 - m_sustainKnob->value() ) ) * - TIME_UNIT_WIDTH ); + p.fillRect( x2, y_base - 1 - avail_height, 2, 2, end_points_color ); - p.drawLine( x1, y_base-avail_height, x2, static_cast( y_base - + p.drawLine( x3, y_base-avail_height, x4, static_cast( y_base - avail_height + ( 1 - m_sustainKnob->value() ) * avail_height ) ); - p.fillRect( x1 - 1, y_base - 2 - avail_height, 4, 4, + p.fillRect( x3 - 1, y_base - 2 - avail_height, 4, 4, end_points_bg_color ); - p.fillRect( x1, y_base - 1 - avail_height, 2, 2, end_points_color ); - x1 = x2; - x2 = x1 + static_cast( m_releaseKnob->value() * TIME_UNIT_WIDTH ); - - p.drawLine( x1, static_cast( y_base - avail_height + + p.fillRect( x3, y_base - 1 - avail_height, 2, 2, end_points_color ); + + p.drawLine( x4, static_cast( y_base - avail_height + ( 1 - m_sustainKnob->value() ) * - avail_height ), x2, y_base ); - p.fillRect( x1 - 1, static_cast( y_base - avail_height + + avail_height ), x5, y_base ); + p.fillRect( x4 - 1, static_cast( y_base - avail_height + ( 1 - m_sustainKnob->value() ) * avail_height ) - 2, 4, 4, end_points_bg_color ); - p.fillRect( x1, static_cast( y_base - avail_height + + p.fillRect( x4, static_cast( y_base - avail_height + ( 1 - m_sustainKnob->value() ) * avail_height ) - 1, 2, 2, end_points_color ); - p.fillRect( x2 - 1, y_base - 2, 4, 4, end_points_bg_color ); - p.fillRect( x2, y_base - 1, 2, 2, end_points_color ); + p.fillRect( x5 - 1, y_base - 2, 4, 4, end_points_bg_color ); + p.fillRect( x5, y_base - 1, 2, 2, end_points_color ); int LFO_GRAPH_W = s_lfoGraph->width() - 6; // substract border