Make LFO controller accept custom waveforms

This commit is contained in:
Wong Cho Ching
2014-01-24 22:55:32 +08:00
parent 9435cfd8b8
commit c45aafc748
11 changed files with 147 additions and 70 deletions

View File

@@ -75,6 +75,8 @@ protected:
sample_t (*m_sampleFunction)( const float );
private:
SampleBuffer * m_userDefSampleBuffer;
protected slots:
void updateSampleFunction();
@@ -107,6 +109,13 @@ protected:
automatableButtonGroup * m_waveBtnGrp;
automatableButtonGroup * m_multiplierBtnGrp;
private:
pixmapButton * m_userWaveBtn;
private slots:
void askUserDefWave();
} ;
#endif

View File

@@ -172,7 +172,8 @@ public:
return m_data;
}
QString openAudioFile() const;
QString openAudioFile() const;
QString openAndSetAudioFile();
QString & toBase64( QString & _dst ) const;

View File

@@ -151,7 +151,7 @@ public slots:
void setWaveToSaw();
void setWaveToSquare();
void setWaveToNoise();
//void setWaveToUser( );
QString setWaveToUser( );
void smooth();
void normalize();

View File

@@ -243,7 +243,7 @@ void bitInvader::normalize()
const float f = fabsf( samples[i] );
if (f > max) { max = f; }
}
normalizeFactor = 1.0 / max;
m_normalizeFactor = 1.0 / max;
}
@@ -270,7 +270,7 @@ void bitInvader::playNote( notePlayHandle * _n,
}
else
{
factor = normalizeFactor;
factor = m_normalizeFactor;
}
_n->m_pluginData = new bSynth(
@@ -350,69 +350,69 @@ bitInvaderView::bitInvaderView( Instrument * _instrument,
m_graph->setPalette( pal );
sinWaveBtn = new pixmapButton( this, tr( "Sine wave" ) );
sinWaveBtn->move( 188, 120 );
sinWaveBtn->setActiveGraphic( embed::getIconPixmap(
m_sinWaveBtn = new pixmapButton( this, tr( "Sine wave" ) );
m_sinWaveBtn->move( 188, 120 );
m_sinWaveBtn->setActiveGraphic( embed::getIconPixmap(
"sin_wave_active" ) );
sinWaveBtn->setInactiveGraphic( embed::getIconPixmap(
m_sinWaveBtn->setInactiveGraphic( embed::getIconPixmap(
"sin_wave_inactive" ) );
toolTip::add( sinWaveBtn,
toolTip::add( m_sinWaveBtn,
tr( "Click for a sine-wave." ) );
triangleWaveBtn = new pixmapButton( this, tr( "Triangle wave" ) );
triangleWaveBtn->move( 188, 136 );
triangleWaveBtn->setActiveGraphic(
m_triangleWaveBtn = new pixmapButton( this, tr( "Triangle wave" ) );
m_triangleWaveBtn->move( 188, 136 );
m_triangleWaveBtn->setActiveGraphic(
embed::getIconPixmap( "triangle_wave_active" ) );
triangleWaveBtn->setInactiveGraphic(
m_triangleWaveBtn->setInactiveGraphic(
embed::getIconPixmap( "triangle_wave_inactive" ) );
toolTip::add( triangleWaveBtn,
toolTip::add( m_triangleWaveBtn,
tr( "Click here for a triangle-wave." ) );
sawWaveBtn = new pixmapButton( this, tr( "Saw wave" ) );
sawWaveBtn->move( 188, 152 );
sawWaveBtn->setActiveGraphic( embed::getIconPixmap(
m_sawWaveBtn = new pixmapButton( this, tr( "Saw wave" ) );
m_sawWaveBtn->move( 188, 152 );
m_sawWaveBtn->setActiveGraphic( embed::getIconPixmap(
"saw_wave_active" ) );
sawWaveBtn->setInactiveGraphic( embed::getIconPixmap(
m_sawWaveBtn->setInactiveGraphic( embed::getIconPixmap(
"saw_wave_inactive" ) );
toolTip::add( sawWaveBtn,
toolTip::add( m_sawWaveBtn,
tr( "Click here for a saw-wave." ) );
sqrWaveBtn = new pixmapButton( this, tr( "Square wave" ) );
sqrWaveBtn->move( 188, 168 );
sqrWaveBtn->setActiveGraphic( embed::getIconPixmap(
m_sqrWaveBtn = new pixmapButton( this, tr( "Square wave" ) );
m_sqrWaveBtn->move( 188, 168 );
m_sqrWaveBtn->setActiveGraphic( embed::getIconPixmap(
"square_wave_active" ) );
sqrWaveBtn->setInactiveGraphic( embed::getIconPixmap(
m_sqrWaveBtn->setInactiveGraphic( embed::getIconPixmap(
"square_wave_inactive" ) );
toolTip::add( sqrWaveBtn,
toolTip::add( m_sqrWaveBtn,
tr( "Click here for a square-wave." ) );
whiteNoiseWaveBtn = new pixmapButton( this,
m_whiteNoiseWaveBtn = new pixmapButton( this,
tr( "White noise wave" ) );
whiteNoiseWaveBtn->move( 188, 184 );
whiteNoiseWaveBtn->setActiveGraphic(
m_whiteNoiseWaveBtn->move( 188, 184 );
m_whiteNoiseWaveBtn->setActiveGraphic(
embed::getIconPixmap( "white_noise_wave_active" ) );
whiteNoiseWaveBtn->setInactiveGraphic(
m_whiteNoiseWaveBtn->setInactiveGraphic(
embed::getIconPixmap( "white_noise_wave_inactive" ) );
toolTip::add( whiteNoiseWaveBtn,
toolTip::add( m_whiteNoiseWaveBtn,
tr( "Click here for white-noise." ) );
usrWaveBtn = new pixmapButton( this, tr( "User defined wave" ) );
usrWaveBtn->move( 188, 200 );
usrWaveBtn->setActiveGraphic( embed::getIconPixmap(
m_usrWaveBtn = new pixmapButton( this, tr( "User defined wave" ) );
m_usrWaveBtn->move( 188, 200 );
m_usrWaveBtn->setActiveGraphic( embed::getIconPixmap(
"usr_wave_active" ) );
usrWaveBtn->setInactiveGraphic( embed::getIconPixmap(
m_usrWaveBtn->setInactiveGraphic( embed::getIconPixmap(
"usr_wave_inactive" ) );
toolTip::add( usrWaveBtn,
toolTip::add( m_usrWaveBtn,
tr( "Click here for a user-defined shape." ) );
smoothBtn = new pixmapButton( this, tr( "Smooth" ) );
smoothBtn->move( 35, 200 );
smoothBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
m_smoothBtn = new pixmapButton( this, tr( "Smooth" ) );
m_smoothBtn->move( 35, 200 );
m_smoothBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
"smooth" ) );
smoothBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
m_smoothBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
"smooth" ) );
smoothBtn->setChecked( true );
toolTip::add( smoothBtn,
m_smoothBtn->setChecked( true );
toolTip::add( m_smoothBtn,
tr( "Click here to smooth waveform." ) );
@@ -426,20 +426,20 @@ bitInvaderView::bitInvaderView( Instrument * _instrument,
m_normalizeToggle->move( 55, 100 );
connect( sinWaveBtn, SIGNAL (clicked () ),
connect( m_sinWaveBtn, SIGNAL (clicked () ),
this, SLOT ( sinWaveClicked() ) );
connect( triangleWaveBtn, SIGNAL ( clicked () ),
connect( m_triangleWaveBtn, SIGNAL ( clicked () ),
this, SLOT ( triangleWaveClicked() ) );
connect( sawWaveBtn, SIGNAL (clicked () ),
connect( m_sawWaveBtn, SIGNAL (clicked () ),
this, SLOT ( sawWaveClicked() ) );
connect( sqrWaveBtn, SIGNAL ( clicked () ),
connect( m_sqrWaveBtn, SIGNAL ( clicked () ),
this, SLOT ( sqrWaveClicked() ) );
connect( whiteNoiseWaveBtn, SIGNAL ( clicked () ),
connect( m_whiteNoiseWaveBtn, SIGNAL ( clicked () ),
this, SLOT ( noiseWaveClicked() ) );
connect( usrWaveBtn, SIGNAL ( clicked () ),
connect( m_usrWaveBtn, SIGNAL ( clicked () ),
this, SLOT ( usrWaveClicked() ) );
connect( smoothBtn, SIGNAL ( clicked () ),
connect( m_smoothBtn, SIGNAL ( clicked () ),
this, SLOT ( smoothClicked() ) );
connect( m_interpolationToggle, SIGNAL( toggled( bool ) ),
@@ -514,6 +514,9 @@ void bitInvaderView::noiseWaveClicked()
void bitInvaderView::usrWaveClicked()
{
QString fileName = m_graph->model()->setWaveToUser();
toolTip::add( m_usrWaveBtn, fileName );
engine::getSong()->setModified();
/*
m_graph->model()->setWaveToNoise();
engine::getSong()->setModified();

View File

@@ -99,7 +99,7 @@ private:
BoolModel m_interpolation;
BoolModel m_normalize;
float normalizeFactor;
float m_normalizeFactor;
oscillator * m_osc;
@@ -136,13 +136,13 @@ private:
virtual void modelChanged();
knob * m_sampleLengthKnob;
pixmapButton * sinWaveBtn;
pixmapButton * triangleWaveBtn;
pixmapButton * sqrWaveBtn;
pixmapButton * sawWaveBtn;
pixmapButton * whiteNoiseWaveBtn;
pixmapButton * smoothBtn;
pixmapButton * usrWaveBtn;
pixmapButton * m_sinWaveBtn;
pixmapButton * m_triangleWaveBtn;
pixmapButton * m_sqrWaveBtn;
pixmapButton * m_sawWaveBtn;
pixmapButton * m_whiteNoiseWaveBtn;
pixmapButton * m_smoothBtn;
pixmapButton * m_usrWaveBtn;
static QPixmap * s_artwork;

View File

@@ -138,10 +138,9 @@ OscillatorObject::~OscillatorObject()
void OscillatorObject::oscUserDefWaveDblClick()
{
QString af = m_sampleBuffer->openAudioFile();
QString af = m_sampleBuffer->openAndSetAudioFile();
if( af != "" )
{
m_sampleBuffer->setAudioFile( af );
// TODO:
//toolTip::add( m_usrWaveBtn, m_sampleBuffer->audioFile() );
}

View File

@@ -728,9 +728,9 @@ void vibedView::noiseWaveClicked()
void vibedView::usrWaveClicked()
{
// TODO: load file
//m_graph->model()->setWaveToUser();
//engine::getSongEditor()->setModified();
QString fileName = m_graph->model()->setWaveToUser();
toolTip::add( m_usrWaveBtn, fileName );
engine::getSong()->setModified();
}

View File

@@ -49,7 +49,8 @@ LfoController::LfoController( Model * _parent ) :
m_duration( 1000 ),
m_phaseCorrection( 0 ),
m_phaseOffset( 0 ),
m_sampleFunction( &Oscillator::sinSample )
m_sampleFunction( &Oscillator::sinSample ),
m_userDefSampleBuffer( new SampleBuffer )
{
connect( &m_waveModel, SIGNAL( dataChanged() ),
@@ -61,6 +62,7 @@ LfoController::LfoController( Model * _parent ) :
LfoController::~LfoController()
{
sharedObject::unref( m_userDefSampleBuffer );
m_baseModel.disconnect( this );
m_speedModel.disconnect( this );
m_amountModel.disconnect( this );
@@ -164,7 +166,9 @@ float LfoController::value( int _offset )
// 44100 frames/sec
return m_baseModel.value() + ( m_amountModel.value() *
m_sampleFunction(sampleFrame)
( m_sampleFunction != NULL ?
m_sampleFunction(sampleFrame):
m_userDefSampleBuffer->userWaveSample(sampleFrame) )
/ 2.0f );
}
@@ -196,6 +200,14 @@ void LfoController::updateSampleFunction()
case Oscillator::WhiteNoise:
m_sampleFunction = &Oscillator::noiseSample;
break;
case Oscillator::UserDefinedWave:
m_sampleFunction = NULL;
/*TODO: If C++11 is allowed, should change the type of
m_sampleFunction be std::function<sample_t(const float)>
and use the line below:
*/
//m_sampleFunction = &(m_userDefSampleBuffer->userWaveSample)
break;
}
}

View File

@@ -894,6 +894,23 @@ QString SampleBuffer::openAudioFile() const
}
QString SampleBuffer::openAndSetAudioFile()
{
QString fileName = this->openAudioFile();
if(!fileName.isEmpty())
{
this->setAudioFile( fileName );
}
return fileName;
}
#undef LMMS_HAVE_FLAC_STREAM_ENCODER_H /* not yet... */
#undef LMMS_HAVE_FLAC_STREAM_DECODER_H

View File

@@ -178,15 +178,17 @@ LfoControllerDialog::LfoControllerDialog( Controller * _model, QWidget * _parent
toolTip::add( white_noise_btn,
tr( "Click here for white-noise." ) );
pixmapButton * uwb = new pixmapButton( this, NULL );
uwb->move( CD_LFO_SHAPES_X + 45, CD_LFO_SHAPES_Y + 15 );
uwb->setActiveGraphic( embed::getIconPixmap(
m_userWaveBtn = new pixmapButton( this, NULL );
m_userWaveBtn->move( CD_LFO_SHAPES_X + 45, CD_LFO_SHAPES_Y + 15 );
m_userWaveBtn->setActiveGraphic( embed::getIconPixmap(
"usr_wave_active" ) );
uwb->setInactiveGraphic( embed::getIconPixmap(
m_userWaveBtn->setInactiveGraphic( embed::getIconPixmap(
"usr_wave_inactive" ) );
uwb->setEnabled( false );
toolTip::add( uwb, tr( "Click here for a user-defined "
"shape." ) );
connect( m_userWaveBtn,
SIGNAL( doubleClicked() ),
this, SLOT( askUserDefWave() ) );
toolTip::add( m_userWaveBtn,
tr( "Click here for a user-defined shape." ) );
m_waveBtnGrp = new automatableButtonGroup( this );
m_waveBtnGrp->addButton( sin_wave_btn );
@@ -196,7 +198,7 @@ LfoControllerDialog::LfoControllerDialog( Controller * _model, QWidget * _parent
m_waveBtnGrp->addButton( moog_saw_wave_btn );
m_waveBtnGrp->addButton( exp_wave_btn );
m_waveBtnGrp->addButton( white_noise_btn );
m_waveBtnGrp->addButton( uwb );
m_waveBtnGrp->addButton( m_userWaveBtn );
pixmapButton * x1 = new pixmapButton( this, NULL );
@@ -240,11 +242,26 @@ LfoControllerDialog::LfoControllerDialog( Controller * _model, QWidget * _parent
LfoControllerDialog::~LfoControllerDialog()
{
m_userWaveBtn->disconnect( this );
//delete m_subWindow;
}
void LfoControllerDialog::askUserDefWave()
{
SampleBuffer * sampleBuffer = dynamic_cast<LfoController*>(this->model())->
m_userDefSampleBuffer;
QString fileName = sampleBuffer->openAndSetAudioFile();
if( fileName.isEmpty() == false )
{
// TODO:
toolTip::add( m_userWaveBtn, sampleBuffer->audioFile() );
}
}
void LfoControllerDialog::contextMenuEvent( QContextMenuEvent * )
{
/*

View File

@@ -482,6 +482,25 @@ void graphModel::setWaveToNoise()
emit samplesChanged( 0, length() - 1 );
};
QString graphModel::setWaveToUser()
{
SampleBuffer * sampleBuffer = new SampleBuffer;
QString fileName = sampleBuffer->openAndSetAudioFile();
if( fileName.isEmpty() == false )
{
for( int i = 0; i < length(); i++ )
{
m_samples[i] = sampleBuffer->userWaveSample(
i / static_cast<float>( length() ) );
}
}
sharedObject::unref( sampleBuffer );
emit samplesChanged( 0, length() - 1 );
return fileName;
};
void graphModel::smooth()