Organic: update artwork, add harmonic knobs to control harmonic of each oscillator

This commit is contained in:
Vesa
2014-04-29 20:13:05 +03:00
parent 46b4fe0302
commit dce6a26eb3
7 changed files with 153 additions and 40 deletions

View File

@@ -545,24 +545,29 @@ AudioFileProcessorView knob {
}
organicInstrumentView knob {
color: rgb(205, 16, 216);
qproperty-outerColor: rgb(23, 9, 24);
/*qproperty-outerColor: rgb(64, 21, 67);*/
color: rgb(124, 207, 98);
qproperty-outerColor: rgb(13, 42, 4);
qproperty-innerRadius: 2;
qproperty-outerRadius: 8.7;
qproperty-outerRadius: 7.5;
qproperty-centerPointX: 10.5;
qproperty-centerPointY: 10.5;
qproperty-lineWidth: 2;
qproperty-lineWidth: 1.5;
}
organicInstrumentView knob#harmKnob {
color: rgb(205, 98, 216);
qproperty-outerColor: rgb(18, 4, 18);
}
organicInstrumentView knob#fx1Knob,
organicInstrumentView knob#volKnob {
color: rgb(157, 157, 157);
qproperty-outerColor: rgb(37, 37, 37);
qproperty-innerRadius: 4;
qproperty-outerRadius: 11.2;
qproperty-outerRadius: 10.0;
qproperty-centerPointX: 18.5;
qproperty-centerPointY: 13.8;
qproperty-lineWidth: 3;
qproperty-lineWidth: 2;
}
sf2InstrumentView knob {

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -42,6 +42,8 @@
#include "embed.cpp"
extern "C"
{
@@ -62,7 +64,7 @@ Plugin::Descriptor PLUGIN_EXPORT organic_plugin_descriptor =
}
QPixmap * organicInstrumentView::s_artwork = NULL;
float * organicInstrument::s_harmonics = NULL;
/***********************************************************************
*
@@ -90,6 +92,8 @@ organicInstrument::organicInstrument( InstrumentTrack * _instrument_track ) :
// Connect events
connect( &m_osc[i]->m_oscModel, SIGNAL( dataChanged() ),
m_osc[i], SLOT ( oscButtonChanged() ) );
connect( &m_osc[i]->m_harmModel, SIGNAL( dataChanged() ),
m_osc[i], SLOT( updateDetuning() ) );
connect( &m_osc[i]->m_volModel, SIGNAL( dataChanged() ),
m_osc[i], SLOT( updateVolume() ) );
connect( &m_osc[i]->m_panModel, SIGNAL( dataChanged() ),
@@ -101,14 +105,37 @@ organicInstrument::organicInstrument( InstrumentTrack * _instrument_track ) :
}
m_osc[0]->m_harmonic = log2f( 0.5f ); // one octave below
/* m_osc[0]->m_harmonic = log2f( 0.5f ); // one octave below
m_osc[1]->m_harmonic = log2f( 0.75f ); // a fifth below
m_osc[2]->m_harmonic = log2f( 1.0f ); // base freq
m_osc[3]->m_harmonic = log2f( 2.0f ); // first overtone
m_osc[4]->m_harmonic = log2f( 3.0f ); // second overtone
m_osc[5]->m_harmonic = log2f( 4.0f ); // .
m_osc[6]->m_harmonic = log2f( 5.0f ); // .
m_osc[7]->m_harmonic = log2f( 6.0f ); // .
m_osc[7]->m_harmonic = log2f( 6.0f ); // .*/
if( s_harmonics == NULL )
{
s_harmonics = new float[ NUM_HARMONICS ];
s_harmonics[0] = log2f( 0.5f );
s_harmonics[1] = log2f( 0.75f );
s_harmonics[2] = log2f( 1.0f );
s_harmonics[3] = log2f( 2.0f );
s_harmonics[4] = log2f( 3.0f );
s_harmonics[5] = log2f( 4.0f );
s_harmonics[6] = log2f( 5.0f );
s_harmonics[7] = log2f( 6.0f );
s_harmonics[8] = log2f( 7.0f );
s_harmonics[9] = log2f( 8.0f );
s_harmonics[10] = log2f( 9.0f );
s_harmonics[11] = log2f( 10.0f );
s_harmonics[12] = log2f( 11.0f );
s_harmonics[13] = log2f( 12.0f );
s_harmonics[14] = log2f( 13.0f );
s_harmonics[15] = log2f( 14.0f );
s_harmonics[16] = log2f( 15.0f );
s_harmonics[17] = log2f( 16.0f );
}
for (int i=0; i < m_numOscillators; i++) {
m_osc[i]->updateVolume();
@@ -142,8 +169,8 @@ void organicInstrument::saveSettings( QDomDocument & _doc, QDomElement & _this )
QString is = QString::number( i );
m_osc[i]->m_volModel.saveSettings( _doc, _this, "vol" + is );
m_osc[i]->m_panModel.saveSettings( _doc, _this, "pan" + is );
_this.setAttribute( "harmonic" + is, QString::number(
powf( 2.0f, m_osc[i]->m_harmonic ) ) );
m_osc[i]->m_harmModel.saveSettings( _doc, _this, "newharmonic" + is );
m_osc[i]->m_detuneModel.saveSettings( _doc, _this, "detune"
+ is );
m_osc[i]->m_oscModel.saveSettings( _doc, _this, "wavetype"
@@ -166,6 +193,15 @@ void organicInstrument::loadSettings( const QDomElement & _this )
m_osc[i]->m_detuneModel.loadSettings( _this, "detune" + is );
m_osc[i]->m_panModel.loadSettings( _this, "pan" + is );
m_osc[i]->m_oscModel.loadSettings( _this, "wavetype" + is );
if( _this.hasAttribute( "newharmonic" + is ) )
{
m_osc[i]->m_harmModel.loadSettings( _this, "newharmonic" + is );
}
else
{
m_osc[i]->m_harmModel.setValue( static_cast<float>( i ) );
}
}
m_volModel.loadSettings( _this, "vol" );
@@ -429,26 +465,40 @@ organicInstrumentView::~organicInstrumentView()
void organicInstrumentView::modelChanged()
{
organicInstrument * oi = castModel<organicInstrument>();
const float y=91.3;
const float rowHeight = 26.52f;
const float x=53.4;
const float colWidth = 23.829f; // 54.4 77.2 220.2
const float y=91.0f;
const float rowHeight = 26.0f;
const float x=53.0f;
const float colWidth = 24.0f;
m_numOscillators = oi->m_numOscillators;
m_fx1Knob->setModel( &oi->m_fx1Model );
m_volKnob->setModel( &oi->m_volModel );
// TODO: Delete existing oscKnobs if they exist
if( m_oscKnobs != NULL )
{
delete[] m_oscKnobs;
}
m_oscKnobs = new OscillatorKnobs[ m_numOscillators ];
// Create knobs, now that we know how many to make
for( int i = 0; i < m_numOscillators; ++i )
{
// setup harmonic knob
knob * harmKnob = new organicKnob( this );
harmKnob->move( x + i * colWidth, y - rowHeight );
harmKnob->setObjectName( "harmKnob" );
connect( &oi->m_osc[i]->m_harmModel, SIGNAL( dataChanged() ),
this, SLOT( updateKnobHint() ) );
// setup waveform-knob
knob * oscKnob = new organicKnob( this );
oscKnob->move( x + i * colWidth, y );
connect( &oi->m_osc[i]->m_oscModel, SIGNAL( dataChanged() ),
this, SLOT( updateKnobHint() ) );
oscKnob->setHintText( tr( "Osc %1 waveform:" ).arg( i + 1 ) + " ", QString() );
// setup volume-knob
@@ -473,17 +523,31 @@ void organicInstrumentView::modelChanged()
+ " ", " " +
tr( "cents" ) );
m_oscKnobs[i] = OscillatorKnobs( volKnob, oscKnob, panKnob, detuneKnob );
m_oscKnobs[i] = OscillatorKnobs( harmKnob, volKnob, oscKnob, panKnob, detuneKnob );
// Attach to models
m_oscKnobs[i].m_volKnob->setModel(
&oi->m_osc[i]->m_volModel );
m_oscKnobs[i].m_oscKnob->setModel(
&oi->m_osc[i]->m_oscModel );
m_oscKnobs[i].m_panKnob->setModel(
&oi->m_osc[i]->m_panModel );
m_oscKnobs[i].m_detuneKnob->setModel(
&oi->m_osc[i]->m_detuneModel );
m_oscKnobs[i].m_harmKnob->setModel( &oi->m_osc[i]->m_harmModel );
m_oscKnobs[i].m_volKnob->setModel( &oi->m_osc[i]->m_volModel );
m_oscKnobs[i].m_oscKnob->setModel( &oi->m_osc[i]->m_oscModel );
m_oscKnobs[i].m_panKnob->setModel( &oi->m_osc[i]->m_panModel );
m_oscKnobs[i].m_detuneKnob->setModel( &oi->m_osc[i]->m_detuneModel );
}
updateKnobHint();
}
void organicInstrumentView::updateKnobHint()
{
organicInstrument * oi = castModel<organicInstrument>();
for( int i = 0; i < m_numOscillators; ++i )
{
const float harm = oi->m_osc[i]->m_harmModel.value();
const float wave = oi->m_osc[i]->m_oscModel.value();
m_oscKnobs[i].m_harmKnob->setHintText( tr( "Osc %1 harmonic:" ) + " ", " (" +
HARMONIC_NAMES[ static_cast<int>( harm ) ] + ")" );
m_oscKnobs[i].m_oscKnob->setHintText( tr( "Osc %1 waveform:" ) + " ", " (" +
WAVEFORM_NAMES[ static_cast<int>( wave ) ] + ")" );
}
}
@@ -495,6 +559,8 @@ OscillatorObject::OscillatorObject( Model * _parent, int _index ) :
m_waveShape( Oscillator::SineWave, 0, Oscillator::NumWaveShapes-1, this ),
m_oscModel( 0.0f, 0.0f, 5.0f, 1.0f,
this, tr( "Osc %1 waveform" ).arg( _index + 1 ) ),
m_harmModel( static_cast<float>( _index ), 0.0f, 17.0f, 1.0f,
this, tr( "Osc %1 harmonic" ).arg( _index + 1 ) ),
m_volModel( 100.0f, 0.0f, 100.0f, 1.0f,
this, tr( "Osc %1 volume" ).arg( _index + 1 ) ),
m_panModel( DefaultPanning, PanningLeft, PanningRight, 1.0f,
@@ -547,10 +613,10 @@ void OscillatorObject::updateVolume()
void OscillatorObject::updateDetuning()
{
m_detuningLeft = powf( 2.0f, m_harmonic
m_detuningLeft = powf( 2.0f, organicInstrument::s_harmonics[ static_cast<int>( m_harmModel.value() ) ]
+ (float)m_detuneModel.value() / 100.0f ) /
engine::mixer()->processingSampleRate();
m_detuningRight = powf( 2.0f, m_harmonic
m_detuningRight = powf( 2.0f, organicInstrument::s_harmonics[ static_cast<int>( m_harmModel.value() ) ]
- (float)m_detuneModel.value() / 100.0f ) /
engine::mixer()->processingSampleRate();
}

View File

@@ -2,7 +2,7 @@
* organic.h - additive synthesizer for organ-like sounds
*
* Copyright (c) 2006-2008 Andreas Brandmaier <andy/at/brandmaier/dot/de>
*
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
@@ -23,8 +23,10 @@
*/
#ifndef _ORGANIC_H
#define _ORGANIC_H
#ifndef ORGANIC_H
#define ORGANIC_H
#include <QString>
#include "Instrument.h"
#include "InstrumentView.h"
@@ -37,6 +39,36 @@ class knob;
class NotePlayHandle;
class pixmapButton;
const int NUM_HARMONICS = 18;
const QString HARMONIC_NAMES[NUM_HARMONICS] = {
"Octave below",
"Fifth below",
"Fundamental",
"2nd harmonic",
"3rd harmonic",
"4th harmonic",
"5th harmonic",
"6th harmonic",
"7th harmonic",
"8th harmonic",
"9th harmonic",
"10th harmonic",
"11th harmonic",
"12th harmonic",
"13th harmonic",
"14th harmonic",
"15th harmonic",
"16th harmonic"
};
const QString WAVEFORM_NAMES[6] = {
"Sine wave",
"Triangle wave",
"Saw wave",
"Square wave",
"Moog saw wave",
"Exponential wave"
};
class OscillatorObject : public Model
{
@@ -45,11 +77,11 @@ private:
int m_numOscillators;
IntModel m_waveShape;
FloatModel m_oscModel;
FloatModel m_harmModel;
FloatModel m_volModel;
FloatModel m_panModel;
FloatModel m_detuneModel;
float m_harmonic;
float m_volumeLeft;
float m_volumeRight;
// normalized detuning -> x/sampleRate
@@ -90,9 +122,10 @@ public:
virtual void loadSettings( const QDomElement & _this );
virtual QString nodeName() const;
int intRand( int min, int max );
static float * s_harmonics;
public slots:
void randomiseSettings();
@@ -101,17 +134,17 @@ public slots:
private:
float inline waveshape(float in, float amount);
// fast atan, fast rather than accurate
inline float fastatan( float x )
{
return (x / (1.0 + 0.28 * (x * x)));
}
int m_numOscillators;
OscillatorObject ** m_osc;
struct oscPtr
{
Oscillator * oscLeft;
@@ -125,6 +158,8 @@ private:
virtual PluginView * instantiateView( QWidget * _parent );
float m_harmonics [18];
private slots:
void updateAllDetuning();
@@ -144,10 +179,13 @@ private:
struct OscillatorKnobs
{
OscillatorKnobs( knob * v,
OscillatorKnobs(
knob * h,
knob * v,
knob * o,
knob * p,
knob * dt ) :
m_harmKnob( h ),
m_volKnob( v ),
m_oscKnob( o ),
m_panKnob( p ),
@@ -157,7 +195,8 @@ private:
OscillatorKnobs()
{
}
knob * m_harmKnob;
knob * m_volKnob;
knob * m_oscKnob;
knob * m_panKnob;
@@ -171,8 +210,11 @@ private:
pixmapButton * m_randBtn;
int m_numOscillators;
static QPixmap * s_artwork;
protected slots:
void updateKnobHint();
};

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB