diff --git a/ChangeLog b/ChangeLog index 4f883b1df..9911ca20f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-01-19 Andreas M. Brandmaier + + * 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 * src/lib/mmp.cpp: diff --git a/configure.in b/configure.in index 775382dbd..8c80d0a20 100644 --- a/configure.in +++ b/configure.in @@ -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 diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 8f5fbb81a..707e95dc6 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -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) diff --git a/plugins/bit_invader/Makefile.am b/plugins/bit_invader/Makefile.am new file mode 100644 index 000000000..57260eeba --- /dev/null +++ b/plugins/bit_invader/Makefile.am @@ -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 diff --git a/plugins/bit_invader/artwork.png b/plugins/bit_invader/artwork.png new file mode 100644 index 000000000..43ee1356f Binary files /dev/null and b/plugins/bit_invader/artwork.png differ diff --git a/plugins/bit_invader/bit_invader.cpp b/plugins/bit_invader/bit_invader.cpp new file mode 100644 index 000000000..471eedcc5 --- /dev/null +++ b/plugins/bit_invader/bit_invader.cpp @@ -0,0 +1,659 @@ +/* + * bit_invader.cpp - instrument which uses a usereditable wavetable + * + * Copyright (c) 2006 Andreas Brandmaier + * + * 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 +#include +#include +#include +#include +#include + +#else + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + +#include +#include +#include +#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 ", + 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(_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( 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(sample_realindex); + int b; + if (a < (sample_length-1)) { + b = static_cast(sample_realindex+1); + } else { + b = 0; + } + + // Nachkommaanteil + float frac = sample_realindex - static_cast(sample_realindex); + + sample = sample_shape[a]*(1-frac) + sample_shape[b]*(frac); + + } else { + // No interpolation + sample_index = static_cast(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( frames ); + + bSynth * ps = static_cast( _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( _n->m_pluginData ); +} + + +void bitInvader::sampleSizeChanged( float _new_sample_length ) +{ + int new_sample_length = static_cast(_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(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( _data ) ) ); +} + + +} + + diff --git a/plugins/bit_invader/bit_invader.h b/plugins/bit_invader/bit_invader.h new file mode 100644 index 000000000..f23a114cb --- /dev/null +++ b/plugins/bit_invader/bit_invader.h @@ -0,0 +1,133 @@ +/* + * bit_invader.h - declaration of class bitInvader and bSynth which + * are a wavetable synthesizer + * + * Copyright (c) 2006 Andreas Brandmaier + * + * 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 + +#else + +#include +#include + +#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 diff --git a/plugins/bit_invader/graph.cpp b/plugins/bit_invader/graph.cpp new file mode 100644 index 000000000..7921c05e9 --- /dev/null +++ b/plugins/bit_invader/graph.cpp @@ -0,0 +1,176 @@ +/* + * graph.cpp - a QT widget for displaying and manipulating waveforms + * + * Copyright (c) 2006 Andreas Brandmaier + * + * 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 +#include +#include + +#else + +#include +#include + +#endif + + +#include "graph.h" + +#include +#include + +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(i*xscale), + static_cast(-samplePointer[i]*50) + 50, + static_cast((i+1)*xscale), + static_cast(-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" diff --git a/plugins/bit_invader/graph.h b/plugins/bit_invader/graph.h new file mode 100644 index 000000000..103bc24e2 --- /dev/null +++ b/plugins/bit_invader/graph.h @@ -0,0 +1,86 @@ +/* + * graph.h - a QT widget for displaying and manipulating waveforms + * + * Copyright (c) 2006 Andreas Brandmaier + * + * 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 +#include + +#else + +#include +#include +#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 diff --git a/plugins/bit_invader/logo.png b/plugins/bit_invader/logo.png new file mode 100644 index 000000000..d7f887c80 Binary files /dev/null and b/plugins/bit_invader/logo.png differ diff --git a/plugins/bit_invader/wavegraph.png b/plugins/bit_invader/wavegraph.png new file mode 100644 index 000000000..4540cf3fa Binary files /dev/null and b/plugins/bit_invader/wavegraph.png differ