Merge pull request #500 from diizy/stable-0.4

Piano widget: fix velocity, Opulenz: increase volume
This commit is contained in:
Tobias Doerffel
2014-03-23 09:35:58 +01:00
6 changed files with 71 additions and 60 deletions

View File

@@ -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>

View File

@@ -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

View File

@@ -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);

View File

@@ -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 ) );

View File

@@ -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

View File

@@ -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