added BitInvader-plugin
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@50 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
@@ -1,3 +1,11 @@
|
||||
2006-01-19 Andreas M. Brandmaier <andy/at/brandmaier.de>
|
||||
|
||||
* plugins/bit_invader/bit_invader.h:
|
||||
* plugins/bit_invader/bit_invader.cpp:
|
||||
* plugins/bit_invader/graph.h:
|
||||
* plugins/bit_invader/graph.cpp:
|
||||
added "BitInvader"-plugin, a usereditable wavetable-synthesizer
|
||||
|
||||
2006-01-16 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
|
||||
* src/lib/mmp.cpp:
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT(lmms, 0.1.2-cvs20060116, tobydox/at/users.sourceforge.net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.1.2-cvs20060116)
|
||||
AC_INIT(lmms, 0.1.2-cvs20060119, tobydox/at/users.sourceforge.net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.1.2-cvs20060119)
|
||||
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
@@ -410,6 +410,7 @@ AC_CONFIG_FILES([Makefile
|
||||
midi-maps/Makefile
|
||||
plugins/Makefile
|
||||
plugins/audio_file_processor/Makefile
|
||||
plugins/bit_invader/Makefile
|
||||
plugins/plucked_string_synth/Makefile
|
||||
plugins/triple_oscillator/Makefile
|
||||
plugins/vestige/Makefile
|
||||
|
||||
@@ -2,6 +2,5 @@ if VST_SUPPORT
|
||||
VESTIGE_SUBDIR=vestige
|
||||
endif
|
||||
|
||||
SUBDIRS = audio_file_processor plucked_string_synth triple_oscillator $(VESTIGE_SUBDIR)
|
||||
|
||||
SUBDIRS = audio_file_processor bit_invader plucked_string_synth triple_oscillator $(VESTIGE_SUBDIR)
|
||||
|
||||
|
||||
33
plugins/bit_invader/Makefile.am
Normal file
33
plugins/bit_invader/Makefile.am
Normal file
@@ -0,0 +1,33 @@
|
||||
AUTOMAKE_OPTIONS = foreign 1.4
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/src/lib -I.
|
||||
|
||||
|
||||
AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS) -DPLUGIN_NAME="bitinvader"
|
||||
|
||||
|
||||
%.moc: ./%.h
|
||||
$(MOC) -o $@ $<
|
||||
|
||||
|
||||
MOC_FILES = ./bit_invader.moc ./graph.moc
|
||||
|
||||
BUILT_SOURCES = $(MOC_FILES) ./embedded_resources.h
|
||||
EMBEDDED_RESOURCES = $(wildcard *png)
|
||||
|
||||
./embedded_resources.h: $(EMBEDDED_RESOURCES)
|
||||
$(top_builddir)/buildtools/bin2res $(EMBEDDED_RESOURCES) > $@
|
||||
|
||||
EXTRA_DIST = $(EMBEDDED_RESOURCES)
|
||||
|
||||
|
||||
CLEANFILES = $(MOC_FILES) ./embedded_resources.h
|
||||
|
||||
|
||||
|
||||
pkglib_LTLIBRARIES= libbitinvader.la
|
||||
|
||||
libbitinvader_la_SOURCES = bit_invader.cpp bit_invader.h graph.cpp graph.h
|
||||
|
||||
$(libbitinvader_la_SOURCES): ./embedded_resources.h
|
||||
BIN
plugins/bit_invader/artwork.png
Normal file
BIN
plugins/bit_invader/artwork.png
Normal file
Binary file not shown.
659
plugins/bit_invader/bit_invader.cpp
Normal file
659
plugins/bit_invader/bit_invader.cpp
Normal file
@@ -0,0 +1,659 @@
|
||||
/*
|
||||
* bit_invader.cpp - instrument which uses a usereditable wavetable
|
||||
*
|
||||
* Copyright (c) 2006 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
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QPainter>
|
||||
#include <QButtonGroup>
|
||||
#include <QBitmap>
|
||||
#include <Qt/QtXml>
|
||||
#include <QFileInfo>
|
||||
#include <QDropEvent>
|
||||
|
||||
#else
|
||||
|
||||
#include <qpainter.h>
|
||||
#include <qbuttongroup.h>
|
||||
#include <qbitmap.h>
|
||||
#include <qdom.h>
|
||||
#include <qfileinfo.h>
|
||||
#include <qdom.h>
|
||||
#include <qmap.h>
|
||||
#include <qcanvas.h>
|
||||
#include <qlabel.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include "math.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
#include "bit_invader.h"
|
||||
#include "channel_track.h"
|
||||
#include "note_play_handle.h"
|
||||
#include "templates.h"
|
||||
#include "buffer_allocator.h"
|
||||
#include "knob.h"
|
||||
#include "pixmap_button.h"
|
||||
#include "tooltip.h"
|
||||
|
||||
#include "embed.cpp"
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
plugin::descriptor bitinvader_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ),
|
||||
"BitInvader",
|
||||
QT_TRANSLATE_NOOP( "pluginBrowser",
|
||||
"Rough & Dirty Wavetable Synthesizer." ),
|
||||
"Andreas Brandmaier <andreas/at/brandmaier/dot/de>",
|
||||
0x0100,
|
||||
plugin::INSTRUMENT,
|
||||
PLUGIN_NAME::findEmbeddedData( "logo.png" )
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
QPixmap * bitInvader::s_artwork = NULL;
|
||||
|
||||
|
||||
bSynth::bSynth(float* shape, int length, float _pitch, bool _interpolation, float factor)
|
||||
{
|
||||
|
||||
interpolation = _interpolation;
|
||||
|
||||
// init variables
|
||||
// sample_length = static_cast<int>(_val1);
|
||||
|
||||
sample_length = length;
|
||||
sample_shape = new float[sample_length];
|
||||
for (int i=0; i < length; i++)
|
||||
{
|
||||
sample_shape[i] = shape[i] * factor;
|
||||
}
|
||||
|
||||
|
||||
sample_index = 0;
|
||||
sample_realindex = 0;
|
||||
|
||||
|
||||
sample_step = static_cast<float>( sample_length /
|
||||
((float)mixer::inst()->sampleRate() / _pitch) );
|
||||
|
||||
/* cout << "Sample length: " << sample_length << endl <<
|
||||
"Sample rate : " << mixer::inst()->sampleRate() << endl <<
|
||||
"Frequency : " << _pitch << endl <<
|
||||
"Sample step : " << sample_step << endl;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
bSynth::~bSynth()
|
||||
{
|
||||
delete[] sample_shape;
|
||||
}
|
||||
|
||||
sampleType bSynth::nextStringSample( void )
|
||||
{
|
||||
|
||||
|
||||
// check overflow
|
||||
while (sample_realindex >= sample_length) {
|
||||
sample_realindex -= sample_length;
|
||||
}
|
||||
|
||||
sampleType sample;
|
||||
|
||||
if (interpolation) {
|
||||
|
||||
// find position in shape
|
||||
int a = static_cast<int>(sample_realindex);
|
||||
int b;
|
||||
if (a < (sample_length-1)) {
|
||||
b = static_cast<int>(sample_realindex+1);
|
||||
} else {
|
||||
b = 0;
|
||||
}
|
||||
|
||||
// Nachkommaanteil
|
||||
float frac = sample_realindex - static_cast<int>(sample_realindex);
|
||||
|
||||
sample = sample_shape[a]*(1-frac) + sample_shape[b]*(frac);
|
||||
|
||||
} else {
|
||||
// No interpolation
|
||||
sample_index = static_cast<int>(sample_realindex);
|
||||
sample = sample_shape[sample_index];
|
||||
}
|
||||
|
||||
// progress in shape
|
||||
sample_realindex += sample_step;
|
||||
|
||||
// cout << sample_index << "\t";
|
||||
|
||||
return sample;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* class BitInvader
|
||||
*
|
||||
* lmms - plugin
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
bitInvader::bitInvader( channelTrack * _channel_track ) :
|
||||
instrument( _channel_track,
|
||||
&bitinvader_plugin_descriptor ),
|
||||
specialBgHandlingWidget( PLUGIN_NAME::getIconPixmap( "artwork" ) )
|
||||
{
|
||||
|
||||
|
||||
m_graph = NULL;
|
||||
normalize = false;
|
||||
interpolation = false;
|
||||
|
||||
if( s_artwork == NULL )
|
||||
{
|
||||
s_artwork = new QPixmap( PLUGIN_NAME::getIconPixmap(
|
||||
"artwork" ) );
|
||||
}
|
||||
|
||||
|
||||
m_pickKnob = new knob( knobDark_28, this, tr( "Samplelength" ) );
|
||||
m_pickKnob->setRange( 8, 128, 1 );
|
||||
m_pickKnob->setValue( 128, TRUE );
|
||||
m_pickKnob->move( 10, 120 );
|
||||
m_pickKnob->setHintText( tr( "Sample Length" ) + " ", "" );
|
||||
|
||||
connect( m_pickKnob, SIGNAL( valueChanged( float ) ),
|
||||
this, SLOT ( sampleSizeChanged( float ) )
|
||||
);
|
||||
|
||||
m_interpolationToggle = new ledCheckBox( "Interpolation", this );
|
||||
m_interpolationToggle->move( 55,80 );
|
||||
|
||||
connect( m_interpolationToggle, SIGNAL( toggled( bool ) ),
|
||||
this, SLOT ( interpolationToggle( bool ) ) );
|
||||
|
||||
m_normalizeToggle = new ledCheckBox( "Normalize", this );
|
||||
m_normalizeToggle->move( 55, 100 );
|
||||
|
||||
connect( m_normalizeToggle, SIGNAL( toggled( bool ) ),
|
||||
this, SLOT ( normalizeToggle( bool ) ) );
|
||||
|
||||
sample_length = 128;
|
||||
sample_shape = new float[128];
|
||||
emit( sinWaveClicked() );
|
||||
|
||||
m_graph = new graph( "", this );
|
||||
m_graph->move(55,120);
|
||||
m_graph->setSamplePointer( sample_shape, sample_length );
|
||||
|
||||
QPixmap p = embed::getIconPixmap("wavegraph") ;
|
||||
|
||||
m_graph->setBackground( &p );
|
||||
|
||||
connect( m_graph, SIGNAL ( sampleSizeChanged( float ) ),
|
||||
this, SLOT (sampleSizeChanged( float ) ) );
|
||||
|
||||
connect( m_graph, SIGNAL ( sampleChanged( void ) ),
|
||||
this, SLOT ( sampleChanged( void ) ) );
|
||||
|
||||
sinWaveBtn = new pixmapButton( this );
|
||||
sinWaveBtn->move( 188, 120 );
|
||||
sinWaveBtn->setActiveGraphic( embed::getIconPixmap(
|
||||
"sin_wave_inactive" ) );
|
||||
sinWaveBtn->setInactiveGraphic( embed::getIconPixmap(
|
||||
"sin_wave_inactive" ) );
|
||||
sinWaveBtn->setChecked( TRUE );
|
||||
toolTip::add( sinWaveBtn,
|
||||
tr( "Click here if you want a sine-wave for "
|
||||
"current oscillator." ) );
|
||||
|
||||
triangleWaveBtn = new pixmapButton( this );
|
||||
triangleWaveBtn->move( 188, 136 );
|
||||
triangleWaveBtn->setActiveGraphic(
|
||||
embed::getIconPixmap( "triangle_wave_inactive" ) );
|
||||
triangleWaveBtn->setInactiveGraphic(
|
||||
embed::getIconPixmap( "triangle_wave_inactive" ) );
|
||||
toolTip::add( triangleWaveBtn,
|
||||
tr( "Click here if you want a triangle-wave "
|
||||
"for current oscillator." ) );
|
||||
|
||||
sawWaveBtn = new pixmapButton( this );
|
||||
sawWaveBtn->move( 188, 152 );
|
||||
sawWaveBtn->setActiveGraphic( embed::getIconPixmap(
|
||||
"saw_wave_inactive" ) );
|
||||
sawWaveBtn->setInactiveGraphic( embed::getIconPixmap(
|
||||
"saw_wave_inactive" ) );
|
||||
toolTip::add( sawWaveBtn,
|
||||
tr( "Click here if you want a saw-wave for "
|
||||
"current oscillator." ) );
|
||||
|
||||
sqrWaveBtn = new pixmapButton( this );
|
||||
sqrWaveBtn->move( 188, 168 );
|
||||
sqrWaveBtn->setActiveGraphic( embed::getIconPixmap(
|
||||
"square_wave_inactive" ) );
|
||||
sqrWaveBtn->setInactiveGraphic( embed::getIconPixmap(
|
||||
"square_wave_inactive" ) );
|
||||
toolTip::add( sqrWaveBtn,
|
||||
tr( "Click here if you want a square-wave for "
|
||||
"current oscillator." ) );
|
||||
|
||||
whiteNoiseWaveBtn = new pixmapButton( this );
|
||||
whiteNoiseWaveBtn->move( 188, 184 );
|
||||
whiteNoiseWaveBtn->setActiveGraphic(
|
||||
embed::getIconPixmap( "white_noise_wave_inactive" ) );
|
||||
whiteNoiseWaveBtn->setInactiveGraphic(
|
||||
embed::getIconPixmap( "white_noise_wave_inactive" ) );
|
||||
toolTip::add( whiteNoiseWaveBtn,
|
||||
tr( "Click here if you want a white-noise for "
|
||||
"current oscillator." ) );
|
||||
|
||||
|
||||
connect( sinWaveBtn, SIGNAL (clicked ( void ) ),
|
||||
this, SLOT ( sinWaveClicked( void ) ) );
|
||||
connect( triangleWaveBtn, SIGNAL ( clicked ( void ) ),
|
||||
this, SLOT ( triangleWaveClicked( void ) ) );
|
||||
connect( sawWaveBtn, SIGNAL (clicked ( void ) ),
|
||||
this, SLOT ( sawWaveClicked( void ) ) );
|
||||
connect( sqrWaveBtn, SIGNAL ( clicked ( void ) ),
|
||||
this, SLOT ( sqrWaveClicked( void ) ) );
|
||||
connect( whiteNoiseWaveBtn, SIGNAL ( clicked ( void ) ),
|
||||
this, SLOT ( noiseWaveClicked( void ) ) );
|
||||
|
||||
#ifdef QT4
|
||||
QPalette pal;
|
||||
pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap(
|
||||
"artwork" ) );
|
||||
setPalette( pal );
|
||||
#else
|
||||
setErasePixmap( PLUGIN_NAME::getIconPixmap( "artwork" ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void bitInvader::paintEvent( QPaintEvent * )
|
||||
{
|
||||
#ifdef QT4
|
||||
QPainter p( this );
|
||||
#else
|
||||
QPixmap pm( rect().size() );
|
||||
pm.fill( this, rect().topLeft() );
|
||||
|
||||
QPainter p( &pm, this );
|
||||
#endif
|
||||
p.drawPixmap( 0, 0, *s_artwork );
|
||||
|
||||
p.setPen( QColor( 255, 255, 255 ) );
|
||||
// p.setPen( QColor( 0xFF, 0xAA, 0x00 ) );
|
||||
|
||||
// p.drawLine(0,0,200,200);
|
||||
|
||||
#ifndef QT4
|
||||
bitBlt( this, rect().topLeft(), &pm );
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void bitInvader::sinWaveClicked( void )
|
||||
{
|
||||
// generate sample data
|
||||
for (int i=0; i < sample_length; i++)
|
||||
{
|
||||
// sin(x)
|
||||
sample_shape[i] = sinf(i * 6.2831853 / sample_length);
|
||||
}
|
||||
|
||||
sampleChanged();
|
||||
}
|
||||
|
||||
|
||||
void bitInvader::triangleWaveClicked( void )
|
||||
{
|
||||
int half_sample_length = sample_length / 2;
|
||||
|
||||
if ((sample_length % 2) == 0) {
|
||||
|
||||
for (int i=0; i < half_sample_length; i++)
|
||||
{
|
||||
// triangle
|
||||
sample_shape[i] = (((float)i) / half_sample_length * 2) - 1;
|
||||
}
|
||||
for (int i=half_sample_length; i < sample_length; i++)
|
||||
{
|
||||
// triangle
|
||||
sample_shape[i] = - (((float)(i-half_sample_length)) / half_sample_length * 2) + 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
for (int i=0; i < half_sample_length; i++)
|
||||
{
|
||||
// triangle
|
||||
sample_shape[i] = (((float)i) / half_sample_length * 2) - 1;
|
||||
}
|
||||
sample_shape[half_sample_length] = 1;
|
||||
for (int i=half_sample_length+1; i < sample_length; i++)
|
||||
{
|
||||
// triangle
|
||||
sample_shape[i] = - (((float)(i-half_sample_length)) / half_sample_length * 2) + 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sampleChanged();
|
||||
}
|
||||
|
||||
void bitInvader::sawWaveClicked( void )
|
||||
{
|
||||
for (int i=0; i < sample_length; i++)
|
||||
{
|
||||
// saw
|
||||
sample_shape[i] = (((float)i) / sample_length * 2) - 1;
|
||||
}
|
||||
|
||||
sampleChanged();
|
||||
}
|
||||
|
||||
void bitInvader::sqrWaveClicked( void )
|
||||
{
|
||||
int half_sample_length = sample_length / 2;
|
||||
|
||||
for (int i=0; i < half_sample_length; i++)
|
||||
{
|
||||
// triangle
|
||||
sample_shape[i] = 1;
|
||||
}
|
||||
for (int i=half_sample_length; i < sample_length; i++)
|
||||
{
|
||||
// triangle
|
||||
sample_shape[i] = -1;
|
||||
}
|
||||
|
||||
sampleChanged();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void bitInvader::noiseWaveClicked( void)
|
||||
{
|
||||
srand(time(NULL));
|
||||
|
||||
for (int i=0; i < sample_length; i++)
|
||||
{
|
||||
sample_shape[i]= ((float)rand() / RAND_MAX * 2.0) - 1.0;
|
||||
}
|
||||
|
||||
sampleChanged();
|
||||
|
||||
}
|
||||
|
||||
bitInvader::~bitInvader()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void bitInvader::saveSettings( QDomDocument & _doc,
|
||||
QDomElement & _parent )
|
||||
{
|
||||
|
||||
QDomElement to_de = _doc.createElement( nodeName() );
|
||||
|
||||
// Save plugin version
|
||||
to_de.setAttribute( "version", "0.1" );
|
||||
|
||||
// Save sample length
|
||||
to_de.setAttribute( "sampleLength", QString::number( sample_length ) );
|
||||
|
||||
// Save sample shape
|
||||
for( int i = 0; i < sample_length; ++i )
|
||||
{
|
||||
QString is = QString::number( i );
|
||||
to_de.setAttribute( "s"+is, QString::number( sample_shape[i] ) );
|
||||
}
|
||||
|
||||
// save sampleLength knob
|
||||
to_de.setAttribute( "knob1", m_pickKnob->value() );
|
||||
|
||||
// save LED normalize
|
||||
to_de.setAttribute( "interpolation", m_interpolationToggle->isChecked() );
|
||||
|
||||
// save LED
|
||||
to_de.setAttribute( "normalize", m_normalizeToggle->isChecked() );
|
||||
|
||||
_parent.appendChild( to_de );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void bitInvader::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
// Load knobs (fires change SIGNAL?)
|
||||
m_pickKnob->setValue( _this.attribute("knob1").toFloat() );
|
||||
|
||||
|
||||
// Load sample length
|
||||
sample_length = _this.attribute( "sampleLength" ).toInt() ;
|
||||
|
||||
// Load sample shape
|
||||
delete[] sample_shape; //TODO: necessary?
|
||||
sample_shape = new float[sample_length];
|
||||
for( int i = 0; i < sample_length; ++i )
|
||||
{
|
||||
QString is = QString::number( i );
|
||||
|
||||
sample_shape[i] = _this.attribute( "s"+is ).toFloat();
|
||||
}
|
||||
|
||||
// Load LED normalize
|
||||
if ( _this.attribute( "interpolation" ).toInt() == 1 ) {
|
||||
m_interpolationToggle->setChecked( true );
|
||||
} else {
|
||||
m_interpolationToggle->setChecked( false );
|
||||
}
|
||||
// Load LED
|
||||
if ( _this.attribute( "normalize" ).toInt() == 1) {
|
||||
m_normalizeToggle->setChecked( true );
|
||||
} else {
|
||||
m_normalizeToggle->setChecked( false );
|
||||
}
|
||||
|
||||
update();
|
||||
// m_graph->update();
|
||||
}
|
||||
|
||||
void bitInvader::interpolationToggle( bool value )
|
||||
{
|
||||
interpolation = value;
|
||||
}
|
||||
|
||||
void bitInvader::normalizeToggle( bool value )
|
||||
{
|
||||
normalize = value;
|
||||
}
|
||||
|
||||
|
||||
QString bitInvader::nodeName( void ) const
|
||||
{
|
||||
return( bitinvader_plugin_descriptor.name );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void bitInvader::playNote( notePlayHandle * _n )
|
||||
{
|
||||
if ( _n->totalFramesPlayed() == 0 )
|
||||
{
|
||||
|
||||
float freq = getChannelTrack()->frequency( _n );
|
||||
|
||||
float factor;
|
||||
if (!normalize) {
|
||||
factor = 1.0;
|
||||
} else {
|
||||
factor = normalizeFactor;
|
||||
}
|
||||
|
||||
_n->m_pluginData = new bSynth( sample_shape, sample_length,freq
|
||||
, interpolation, factor
|
||||
//, m_pickKnob->value()
|
||||
//m_pickupKnob->value()
|
||||
);
|
||||
}
|
||||
|
||||
const Uint32 frames = mixer::inst()->framesPerAudioBuffer();
|
||||
sampleFrame * buf = bufferAllocator::alloc<sampleFrame>( frames );
|
||||
|
||||
bSynth * ps = static_cast<bSynth *>( _n->m_pluginData );
|
||||
for( Uint32 frame = 0; frame < frames; ++frame )
|
||||
{
|
||||
const sampleType cur = ps->nextStringSample();
|
||||
for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
|
||||
{
|
||||
buf[frame][chnl] = cur;
|
||||
}
|
||||
}
|
||||
|
||||
getChannelTrack()->processAudioBuffer( buf, frames, _n );
|
||||
|
||||
bufferAllocator::free( buf );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void bitInvader::deleteNotePluginData( notePlayHandle * _n )
|
||||
{
|
||||
delete static_cast<bSynth *>( _n->m_pluginData );
|
||||
}
|
||||
|
||||
|
||||
void bitInvader::sampleSizeChanged( float _new_sample_length )
|
||||
{
|
||||
int new_sample_length = static_cast<int>(_new_sample_length);
|
||||
|
||||
// ** grow array
|
||||
if (new_sample_length > sample_length) {
|
||||
|
||||
// store values in temporary array
|
||||
float* temp = new float[sample_length];
|
||||
for (int i=0; i < sample_length; i++)
|
||||
{
|
||||
temp[i] = sample_shape[i];
|
||||
}
|
||||
|
||||
// reinitialize sample array
|
||||
delete[] sample_shape;
|
||||
sample_shape = new float[new_sample_length];
|
||||
for (int i=0; i < new_sample_length; i++)
|
||||
{
|
||||
sample_shape[i] = 0;
|
||||
}
|
||||
|
||||
// fill in old values
|
||||
for (int i=0; i < sample_length; i++)
|
||||
{
|
||||
sample_shape[i] = temp[i];
|
||||
}
|
||||
|
||||
delete[] temp;
|
||||
sample_length = new_sample_length;
|
||||
|
||||
}
|
||||
|
||||
// ** shrink array
|
||||
if (new_sample_length < sample_length) {
|
||||
|
||||
sample_length = new_sample_length;
|
||||
|
||||
}
|
||||
|
||||
// sample_length = static_cast<int>(value);
|
||||
// delete[] sample_shape;
|
||||
// sample_shape = new float[sample_length];
|
||||
|
||||
// ** repaint
|
||||
|
||||
m_graph->setSamplePointer( sample_shape, sample_length );
|
||||
m_graph->repaint();
|
||||
}
|
||||
|
||||
void bitInvader::sampleChanged()
|
||||
{
|
||||
|
||||
// analyze
|
||||
float max = 0;
|
||||
for (int i=0; i < sample_length; i++)
|
||||
{
|
||||
if (fabs(sample_shape[i]) > max) { max = fabs(sample_shape[i]); }
|
||||
}
|
||||
normalizeFactor = 1.0 / max;
|
||||
|
||||
// cout << "MAX:" << max << "\tnormalizeFactor : " << normalizeFactor << endl;
|
||||
|
||||
// update
|
||||
if (m_graph != NULL) {
|
||||
m_graph->update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// neccessary for getting instance out of shared lib
|
||||
plugin * lmms_plugin_main( void * _data )
|
||||
{
|
||||
return( new bitInvader(
|
||||
static_cast<channelTrack *>( _data ) ) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
133
plugins/bit_invader/bit_invader.h
Normal file
133
plugins/bit_invader/bit_invader.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* bit_invader.h - declaration of class bitInvader and bSynth which
|
||||
* are a wavetable synthesizer
|
||||
*
|
||||
* Copyright (c) 2006 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
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _BIT_INVADER_H
|
||||
#define _BIT_INVADER_H
|
||||
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
#else
|
||||
|
||||
#include <qpixmap.h>
|
||||
#include <qwidget.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "instrument.h"
|
||||
#include "spc_bg_hndl_widget.h"
|
||||
#include "graph.h"
|
||||
#include "led_checkbox.h"
|
||||
|
||||
|
||||
class knob;
|
||||
class notePlayHandle;
|
||||
class pixmapButton;
|
||||
|
||||
class bSynth
|
||||
{
|
||||
public:
|
||||
bSynth(float* sample, int length, float _pitch, bool _interpolation, float factor);
|
||||
virtual ~bSynth();
|
||||
|
||||
sampleType nextStringSample();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
int sample_index;
|
||||
float sample_realindex;
|
||||
int sample_length;
|
||||
float* sample_shape;
|
||||
float sample_step;
|
||||
|
||||
bool interpolation;
|
||||
} ;
|
||||
|
||||
class bitInvader : public instrument, public specialBgHandlingWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
bitInvader(channelTrack * _channel_track );
|
||||
virtual ~bitInvader();
|
||||
|
||||
virtual void FASTCALL playNote( notePlayHandle * _n );
|
||||
virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n );
|
||||
|
||||
|
||||
virtual void FASTCALL saveSettings( QDomDocument & _doc,
|
||||
QDomElement & _parent );
|
||||
virtual void FASTCALL loadSettings( const QDomElement & _this );
|
||||
|
||||
virtual QString nodeName( void ) const;
|
||||
|
||||
public slots:
|
||||
void sampleSizeChanged( float _new_sample_length );
|
||||
void sampleChanged( void );
|
||||
void interpolationToggle( bool value );
|
||||
void normalizeToggle( bool value );
|
||||
void sinWaveClicked( void );
|
||||
void triangleWaveClicked( void );
|
||||
void sqrWaveClicked( void );
|
||||
void sawWaveClicked( void );
|
||||
void noiseWaveClicked( void );
|
||||
|
||||
protected:
|
||||
virtual void paintEvent( QPaintEvent * );
|
||||
|
||||
|
||||
private:
|
||||
knob * m_pickKnob;
|
||||
knob * m_pickupKnob;
|
||||
|
||||
pixmapButton * sinWaveBtn;
|
||||
pixmapButton * triangleWaveBtn;
|
||||
pixmapButton * sqrWaveBtn;
|
||||
pixmapButton * sawWaveBtn;
|
||||
pixmapButton * whiteNoiseWaveBtn;
|
||||
|
||||
static QPixmap * s_artwork;
|
||||
|
||||
graph * m_graph;
|
||||
ledCheckBox * m_interpolationToggle;
|
||||
ledCheckBox * m_normalizeToggle;
|
||||
|
||||
int sample_length;
|
||||
float* sample_shape;
|
||||
|
||||
bool interpolation;
|
||||
bool normalize;
|
||||
float normalizeFactor;
|
||||
} ;
|
||||
|
||||
|
||||
#include "bit_invader.moc"
|
||||
|
||||
|
||||
#endif
|
||||
176
plugins/bit_invader/graph.cpp
Normal file
176
plugins/bit_invader/graph.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* graph.cpp - a QT widget for displaying and manipulating waveforms
|
||||
*
|
||||
* Copyright (c) 2006 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
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QPaintEvent>
|
||||
#include <QFontMetrics>
|
||||
#include <QPainter>
|
||||
|
||||
#else
|
||||
|
||||
#include <qfontmetrics.h>
|
||||
#include <qpainter.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "graph.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
graph::graph( const QString & _text, QWidget * _parent) :
|
||||
QWidget( _parent )
|
||||
{
|
||||
|
||||
m_background = 0;
|
||||
|
||||
setFixedSize( 128, 101 );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
graph::~graph()
|
||||
{
|
||||
delete m_background;
|
||||
}
|
||||
|
||||
void graph::setBackground( QPixmap * pixmap )
|
||||
{
|
||||
// m_background = pixmap;
|
||||
// setErasePixmap ( *m_background );
|
||||
|
||||
}
|
||||
|
||||
void graph::setSamplePointer( float * pointer, int length )
|
||||
{
|
||||
samplePointer = pointer;
|
||||
sampleLength = length;
|
||||
}
|
||||
|
||||
void graph::mouseMoveEvent ( QMouseEvent * _me )
|
||||
{
|
||||
|
||||
|
||||
// get position
|
||||
int x = _me->x();
|
||||
if (x < 0) { return; }
|
||||
if (x > sampleLength) { return; }
|
||||
|
||||
int y = _me->y();
|
||||
if (y < 0) { return; }
|
||||
if (y >= 100) { return; }
|
||||
|
||||
y = 100 - y;
|
||||
|
||||
samplePointer[x] = (y-50.0)/50.0;
|
||||
|
||||
emit sampleChanged();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void graph::mousePressEvent( QMouseEvent * _me )
|
||||
{
|
||||
/* if( _me->button() == Qt::LeftButton )
|
||||
{
|
||||
toggle();
|
||||
}*/
|
||||
|
||||
|
||||
// get position
|
||||
int x = _me->x();
|
||||
if (x < 0) { return; }
|
||||
if (x > sampleLength) { return; }
|
||||
|
||||
int y = _me->y();
|
||||
if (y < 0) { return; }
|
||||
if (y >= 100) { return; }
|
||||
|
||||
y = 100 - y;
|
||||
|
||||
samplePointer[x] = (y-50.0)/50.0;
|
||||
|
||||
emit sampleChanged();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void sampleChanged() {}
|
||||
|
||||
|
||||
void graph::paintEvent( QPaintEvent * )
|
||||
{
|
||||
|
||||
#ifdef QT4
|
||||
QPainter p( this );
|
||||
#else
|
||||
QPixmap draw_pm( rect().size() );
|
||||
draw_pm.fill( this, rect().topLeft() );
|
||||
|
||||
QPainter p( &draw_pm, this );
|
||||
#endif
|
||||
|
||||
if (m_background != 0) {
|
||||
p.drawPixmap( 0, 0, *m_background );
|
||||
}
|
||||
|
||||
p.setPen( QColor( 0xFF, 0xAA, 0x00 ) );
|
||||
|
||||
p.drawLine( sampleLength, 0, sampleLength, 100);
|
||||
|
||||
// float xscale = 200.0 / sampleLength;
|
||||
float xscale = 1.0;
|
||||
|
||||
for (int i=0; i < sampleLength-1; i++)
|
||||
{
|
||||
p.drawLine(static_cast<int>(i*xscale),
|
||||
static_cast<int>(-samplePointer[i]*50) + 50,
|
||||
static_cast<int>((i+1)*xscale),
|
||||
static_cast<int>(-samplePointer[i+1]*50 + 50)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#ifndef QT4
|
||||
// and blit all the drawn stuff on the screen...
|
||||
bitBlt( this, rect().topLeft(), &draw_pm );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "graph.moc"
|
||||
86
plugins/bit_invader/graph.h
Normal file
86
plugins/bit_invader/graph.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* graph.h - a QT widget for displaying and manipulating waveforms
|
||||
*
|
||||
* Copyright (c) 2006 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
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _GRAPH_H
|
||||
#define _GRAPH_H
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPixmap>
|
||||
|
||||
#else
|
||||
|
||||
#include <qwidget.h>
|
||||
#include <qpixmap.h>
|
||||
#endif
|
||||
|
||||
|
||||
//class QPixmap;
|
||||
|
||||
|
||||
class graph : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/* enum ledColors
|
||||
{
|
||||
YELLOW, GREEN, TOTAL_COLORS
|
||||
} ;
|
||||
*/
|
||||
graph( const QString & _txt, QWidget * _parent//,
|
||||
//ledColors _color = YELLOW
|
||||
);
|
||||
virtual ~graph();
|
||||
|
||||
|
||||
void setSamplePointer( float * pointer, int length );
|
||||
|
||||
void setBackground ( QPixmap * pixmap );
|
||||
|
||||
signals:
|
||||
void sampleSizeChanged( float f );
|
||||
void sampleChanged( void );
|
||||
|
||||
protected:
|
||||
virtual void paintEvent( QPaintEvent * _pe );
|
||||
virtual void mousePressEvent( QMouseEvent * _me );
|
||||
virtual void mouseMoveEvent( QMouseEvent * _me );
|
||||
|
||||
private:
|
||||
QPixmap * m_background;
|
||||
|
||||
|
||||
float *samplePointer;
|
||||
int sampleLength;
|
||||
|
||||
//signals:
|
||||
// void toggled( bool );
|
||||
|
||||
} ;
|
||||
|
||||
#endif
|
||||
BIN
plugins/bit_invader/logo.png
Normal file
BIN
plugins/bit_invader/logo.png
Normal file
Binary file not shown.
BIN
plugins/bit_invader/wavegraph.png
Normal file
BIN
plugins/bit_invader/wavegraph.png
Normal file
Binary file not shown.
Reference in New Issue
Block a user