Merge pull request #500 from diizy/stable-0.4
Piano widget: fix velocity, Opulenz: increase volume
This commit is contained in:
@@ -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 <QtGui/QWidget>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<<n ) * X, X = 0.11597 for A, 0.6311 for D/R
|
||||
// - attack 0.0, 0.23194, 0.46388, 0.92776, 1.85552, 3.71104, 7.42208, 14.84416,
|
||||
// - attack 0.0, 0.23194, 0.46388, 0.92776, 1.85552, 3.71104, 7.42208, 14.84416,
|
||||
// 29.68832, 59.37664, 118.75328, 237.50656, 475.01312, 950.02624, 1900.05248, 3800.10496
|
||||
// -decay/release 0.0, 1.2622, 2.5244, 5.0488, 10.0976, 20.1952, 40.3904, 80.7808, 161.5616,
|
||||
// -decay/release 0.0, 1.2622, 2.5244, 5.0488, 10.0976, 20.1952, 40.3904, 80.7808, 161.5616,
|
||||
// 323.1232, 646.2464, 1292.4928, 2584.9856, 5169.9712, 10339.9424, 20679.8848
|
||||
|
||||
#include "opl2instrument.h"
|
||||
@@ -250,14 +250,14 @@ void opl2instrument::setVoiceVelocity(int voice, int vel) {
|
||||
} else {
|
||||
vel_adjusted = 63 - op1_lvl_mdl.value();
|
||||
}
|
||||
theEmulator->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);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* for testing + according model class
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
*
|
||||
* 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 ) );
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* for testing + according model class
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -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<int>( m_predelayKnob->value<float>() *
|
||||
TIME_UNIT_WIDTH );
|
||||
int x2 = x1 + static_cast<int>( m_attackKnob->value<float>() *
|
||||
TIME_UNIT_WIDTH );
|
||||
int x1 = static_cast<int>( m_predelayKnob->value<float>() * TIME_UNIT_WIDTH );
|
||||
int x2 = x1 + static_cast<int>( m_attackKnob->value<float>() * TIME_UNIT_WIDTH );
|
||||
int x3 = x2 + static_cast<int>( m_holdKnob->value<float>() * TIME_UNIT_WIDTH );
|
||||
int x4 = x3 + static_cast<int>( ( m_decayKnob->value<float>() *
|
||||
( 1 - m_sustainKnob->value<float>() ) ) * TIME_UNIT_WIDTH );
|
||||
int x5 = x4 + static_cast<int>( m_releaseKnob->value<float>() * 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<int>( m_holdKnob->value<float>() * 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<int>( ( m_decayKnob->value<float>() *
|
||||
( 1 - m_sustainKnob->value<float>() ) ) *
|
||||
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<int>( y_base -
|
||||
p.drawLine( x3, y_base-avail_height, x4, static_cast<int>( y_base -
|
||||
avail_height +
|
||||
( 1 - m_sustainKnob->value<float>() ) * 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<int>( m_releaseKnob->value<float>() * TIME_UNIT_WIDTH );
|
||||
|
||||
p.drawLine( x1, static_cast<int>( y_base - avail_height +
|
||||
p.fillRect( x3, y_base - 1 - avail_height, 2, 2, end_points_color );
|
||||
|
||||
p.drawLine( x4, static_cast<int>( y_base - avail_height +
|
||||
( 1 - m_sustainKnob->value<float>() ) *
|
||||
avail_height ), x2, y_base );
|
||||
p.fillRect( x1 - 1, static_cast<int>( y_base - avail_height +
|
||||
avail_height ), x5, y_base );
|
||||
p.fillRect( x4 - 1, static_cast<int>( y_base - avail_height +
|
||||
( 1 - m_sustainKnob->value<float>() ) *
|
||||
avail_height ) - 2, 4, 4,
|
||||
end_points_bg_color );
|
||||
p.fillRect( x1, static_cast<int>( y_base - avail_height +
|
||||
p.fillRect( x4, static_cast<int>( y_base - avail_height +
|
||||
( 1 - m_sustainKnob->value<float>() ) *
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user