On Sunday 25 October 2009, Tobias Doerffel wrote:
> Hi Torsten,
>
> Am Sonntag, 25. Oktober 2009 18:02:03 schrieb Torsten Duwe:
> > I found LMMS did not include one of my favority synths, the DX7
> > emulator "hexter" http://dssi.sourceforge.net/hexter.html ,
> > so I hacked up some glue to achieve this.
>
> Great stuff - thanks :)
> I just took a rough look at the sources. If you plan this to be integrated
> into LMMS finally your source should match LMMS' coding style guidelines
> (see Wiki) - mainly indentation currently is broken in your files. Use tab
> for each level of indentation (with ts=4 code should look fine).

This should be better.

        Torsten
/*
 * hexter.h - 
 *
 * Copyright (c) 2009 Torsten Duwe
 * 
 * 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., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA.
 *
 */


#ifndef _HEXTER_LMMS_H
#define _HEXTER_LMMS_H


#include "instrument.h"
#include "instrument_view.h"
#include "automatable_model.h"

extern "C"
{
#include "hexter_synth.h"
#include "dx7_voice_data.h"
#include "dx7_voice.h"
}

class QPixmap;
class pixmapButton;

class HexterInstrument:public instrument
{
	Q_OBJECT 
 public:
	HexterInstrument( instrumentTrack * _instrument_track );
	virtual ~HexterInstrument();

	inline virtual bool isMidiBased() const
	{
		return true;
	}
	virtual bool handleMidiEvent( const midiEvent &, const midiTime & );
	virtual void play( sampleFrame * _working_buffer );

	virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent );
	virtual void loadSettings( const QDomElement & _this );

	virtual QString nodeName( void ) const;

 private:
	hexter_instance_t * m_instance;

	virtual pluginView *instantiateView( QWidget * _parent );

	// private slots:

	friend class HexterInstrumentView;
};


class HexterInstrumentView:public instrumentView
{
	Q_OBJECT
 public:
	HexterInstrumentView( instrument * _instrument, QWidget * _parent );
	virtual ~HexterInstrumentView();

 private:
	virtual void modelChanged( void );

	static QPixmap *s_artwork;
};

#endif

/*
 Local Variables:
 tab-width: 4
 End:
*/
/*
 * hexter.cpp - 
 *
 * Copyright (C) 2004, 2009 Sean Bolton and others.
 * Copyright (c) 2009 Torsten Duwe
 * 
 * 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., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA.
 *
 */


#include "hexter-lmms.h"

#include <QtXml/QDomElement>
#include <QtGui/QPainter>

#include "engine.h"
#include "instrument_track.h"
#include "note_play_handle.h"
#include "instrument_play_handle.h"
#include "pixmap_button.h"
#include "templates.h"
#include "tooltip.h"

#include "embed.cpp"

hexter_synth_t hexter_synth;

plugin::descriptor PLUGIN_EXPORT hexter_plugin_descriptor =
{
	STRINGIFY( PLUGIN_NAME ),
	"Hexter",
	QT_TRANSLATE_NOOP( "pluginBrowser", "DX-7 emu" ),
	"Sean Bolton et al.",
	0x0100,
	plugin::Instrument, new pluginPixmapLoader( "logo" ), NULL, NULL
};

QPixmap *HexterInstrumentView::s_artwork = NULL;

float tuning_normal = 440.0;
float volume_normal = 1.0;

/*
 *	hexter_instantiate adapted from hexter.c
 */

hexter_instance_t *hexter_instantiate( unsigned long _sample_rate )
{
	hexter_instance_t *instance;
	int i;

	hexter_synth.instance_count = 0;
	hexter_synth.instances = NULL;
	hexter_synth.nugget_remains = 0;
	hexter_synth.note_id = 0;
	hexter_synth.global_polyphony = HEXTER_DEFAULT_POLYPHONY;

	for ( i = 0; i < HEXTER_MAX_POLYPHONY; i++ )
	{
		hexter_synth.voice[i] = dx7_voice_new();
		if ( !hexter_synth.voice[i] )
		{
			DEBUG_MESSAGE( -1, " hexter_instantiate: out of memory!\n" );
			return NULL;
		}
	}

	instance =
		( hexter_instance_t * ) calloc( 1, sizeof( hexter_instance_t ) );
	if ( !instance )
	{
		return NULL;
	}
	instance->next = hexter_synth.instances;
	hexter_synth.instances = instance;
	hexter_synth.instance_count++;

	/* do any per-instance one-time initialization here */
	pthread_mutex_init( &instance->patches_mutex, NULL );

	if ( !( instance->patches =
			( dx7_patch_t * ) malloc( 128 * DX7_VOICE_SIZE_PACKED ) ) )
	{
		DEBUG_MESSAGE( -1, " hexter_instantiate: out of memory!\n" );
		return NULL;
	}

	instance->sample_rate = ( float ) _sample_rate;
	dx7_eg_init_constants( instance );	/* depends on sample rate */

	instance->polyphony = HEXTER_DEFAULT_POLYPHONY;
	instance->monophonic = DSSP_MONO_MODE_OFF;
	instance->max_voices = instance->polyphony;
	instance->current_voices = 0;
	instance->last_key = 0;
	instance->pending_program_change = -1;
	instance->current_program = 0;
	instance->overlay_program = -1;

	// Done in hexter_connect_port(LADSPA_Handle, ...), which we do not have:
	instance->tuning = &tuning_normal;
	instance->volume = &volume_normal;

	hexter_data_performance_init( instance->performance_buffer );
	hexter_data_patches_init( instance->patches );
	hexter_instance_select_program( instance, 0, 0 );
	hexter_instance_init_controls( instance );

	return instance;
}




HexterInstrument::HexterInstrument( instrumentTrack * _instrument_track ):
	instrument( _instrument_track, &hexter_plugin_descriptor )
{
	dx7_voice_init_tables();
	m_instance =
		hexter_instantiate( engine::getMixer()->processingSampleRate() );

	instrumentPlayHandle *iph = new instrumentPlayHandle( this );
	engine::getMixer()->addPlayHandle( iph );
}




/*
 *	hexter_handle_event adapted from hexter.c
 */
bool HexterInstrument::handleMidiEvent( const midiEvent & _e,
										const midiTime & _t )
{
	switch ( _e.m_type )
	{
	case MidiNoteOff:
		hexter_instance_note_off( m_instance,
								  _e.m_data.m_param[0],
								  _e.m_data.m_param[1] );
		break;

	case MidiNoteOn:
		if ( _e.m_data.m_param[1] > 0 )
			hexter_instance_note_on( m_instance,
									 _e.m_data.m_param[0],
									 _e.m_data.m_param[1] );
		else
			/* shouldn't happen, but... */
			hexter_instance_note_off( m_instance, _e.m_data.m_param[0], 64 );
		break;

	case MidiKeyPressure:
		hexter_instance_key_pressure( m_instance,
									  _e.m_data.m_param[0],
									  _e.m_data.m_param[1] );
		break;

	case MidiControlChange:
		hexter_instance_control_change( m_instance,
										_e.m_data.m_param[0],
										_e.m_data.m_param[1] );

		break;
#ifdef notyet
	case MidiChannelPressure:
		hexter_instance_channel_pressure( m_instance,
										  event->data.control.value );
		break;

	case MidiPitchBend:
		hexter_instance_pitch_bend( m_instance, event->data.control.value );
		break;

	case MidiProgramChange:
		hexter_select_program( m_instance, event->data.control.value );
		break;
#endif

		/* SND_SEQ_EVENT_SYSEX - shouldn't happen */
		/* SND_SEQ_EVENT_CONTROL14? */
		/* SND_SEQ_EVENT_NONREGPARAM? */
		/* SND_SEQ_EVENT_REGPARAM? */
	default:
		break;
	}
	return true;
}




HexterInstrument::~HexterInstrument()
{
	engine::getMixer()->removePlayHandles( getInstrumentTrack() );
// closePlugin();
}




void HexterInstrument::saveSettings( QDomDocument & _doc,
									 QDomElement & _this )
{
}




void HexterInstrument::loadSettings( const QDomElement & _this )
{
}




QString HexterInstrument::nodeName( void ) const
{
	return hexter_plugin_descriptor.name;
}




/*
 *	hexter_synth_render_voices adapted from hexter_synth.c
 */
void HexterInstrument::play( sampleFrame * _working_buffer )
{
	f_cnt_t nframes = engine::getMixer()->framesPerPeriod();
	long i;
	dx7_voice_t *voice;

	int sample_count = nframes;

	float *monobuf = new float[nframes];

	/* update each LFO */
	dx7_lfo_update( m_instance, sample_count );
	for ( i = 0; i < nframes; i++ )
	{
		monobuf[i] = 0.0;
	}

	/* render each active voice */
	for ( i = 0; i < hexter_synth.global_polyphony; i++ )
	{
		voice = hexter_synth.voice[i];

		if ( _PLAYING( voice ) && voice->instance == m_instance )
		{
			if ( voice->mods_serial != voice->instance->mods_serial )
			{
				dx7_voice_update_mod_depths( voice->instance, voice );
				voice->mods_serial = voice->instance->mods_serial;
			}
			dx7_voice_render( m_instance, voice,
							  monobuf, nframes, 1 /* do_control_update */  );
		}
	}
	for ( i = 0; i < nframes; i++ )
	{
		_working_buffer[i][0] = monobuf[i];
		_working_buffer[i][1] = monobuf[i];
	}
	getInstrumentTrack()->processAudioBuffer( _working_buffer, nframes, 0 );
	delete monobuf;
}




pluginView *HexterInstrument::instantiateView( QWidget * _parent )
{
	return new HexterInstrumentView( this, _parent );
}




HexterInstrumentView::HexterInstrumentView( instrument * _instrument,
											QWidget * _parent ):
	instrumentView( _instrument, _parent )
{
	//    HexterInstrument * oi = castModel<HexterInstrument>();

	setAutoFillBackground( TRUE );
	QPalette pal;

	pal.setBrush( backgroundRole(),
				  PLUGIN_NAME::getIconPixmap( "artwork" ) );
	setPalette( pal );

	if ( s_artwork == NULL )
	{
		s_artwork = new QPixmap( PLUGIN_NAME::getIconPixmap( "artwork" ) );
	}

}




HexterInstrumentView::~HexterInstrumentView()
{
}




void HexterInstrumentView::modelChanged( void )
{
	//    HexterInstrument * oi = castModel<HexterInstrument>();
}




extern "C"
{
// neccessary for getting instance out of shared lib
	plugin *PLUGIN_EXPORT lmms_plugin_main( model *, void *_data )
	{
		return new HexterInstrument( static_cast <
									 instrumentTrack * >( _data ) );
	}
}

#include "moc_hexter-lmms.cxx"

/*
 Local Variables:
 tab-width: 4
 End:
*/
------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
LMMS-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/lmms-devel

Reply via email to