Example #1
0
sample filter::update (sample _in0)
{
    sample out;

    switch(m_coef->m_type)
    {
    case filter_values::MOOG: {
	sample x = _in0 - m_r*m_y4;

	// four cascaded onepole filters
	// (bilinear transform)
	m_y1 = tLimit(( x + m_oldx ) * m_p - m_k * m_y1,
		      -10.0f, 10.0f );
	m_y2 = tLimit(( m_y1 + m_oldy1 ) * m_p - m_k * m_y2,
		      -10.0f, 10.0f );
	m_y3 = tLimit(( m_y2 + m_oldy2 ) * m_p - m_k * m_y3,
		      -10.0f, 10.0f );
	m_y4 = tLimit(( m_y3 + m_oldy3 ) * m_p - m_k * m_y4,
		      -10.0f, 10.0f );

	m_oldx = x;
	m_oldy1 = m_y1;
	m_oldy2 = m_y2;
	m_oldy3 = m_y3;

	out = m_y4 - m_y4 * m_y4 *
	    m_y4 * ( 1.0f / 6.0f );

	break;
    }
	
    default:
	// filter
	out = m_b0a0 * _in0 +
	    m_b1a0 * m_in1 +
	    m_b2a0 * m_in2 -
	    m_a1a0 * m_ou1 -
	    m_a2a0 * m_ou2;
   
	// push in/out buffers
	m_in2 = m_in1;
	m_in1 = _in0;
	m_ou2 = m_ou1;

	m_ou1 = out;
	break;
    }

    return out;
}
Example #2
0
/*! \brief Get the key from the mouse position in the piano display
 *
 *  First we determine it roughly by the position of the point given in
 *  white key widths from our start.  We then add in any black keys that
 *  might have been skipped over (they take a key number, but no 'white
 *  key' space).  We then add in our starting key number.
 *
 *  We then determine whether it was a black key that was pressed by
 *  checking whether it was within the vertical range of black keys.
 *  Black keys sit exactly between white keys on this keyboard, so
 *  we then shift the note down or up if we were in the left or right
 *  half of the white note.  We only do this, of course, if the white
 *  note has a black key on that side, so to speak.
 *
 *  This function returns const because there is a linear mapping from
 *  the point given to the key returned that never changes.
 *
 *  \param _p The point that the mouse was pressed.
 */
int PianoView::getKeyFromMouse( const QPoint & _p ) const
{
	int key_num = (int)( (float) _p.x() / (float) PW_WHITE_KEY_WIDTH );

	for( int i = 0; i <= key_num; ++i )
	{
		if( KEY_ORDER[( m_startKey+i ) % KeysPerOctave] ==
							Piano::BlackKey )
		{
			++key_num;
		}
	}

	key_num += m_startKey;

	// is it a black key?
	if( _p.y() < PIANO_BASE + PW_BLACK_KEY_HEIGHT )
	{
		// then do extra checking whether the mouse-cursor is over
		// a black key
		if( key_num > 0 && KEY_ORDER[(key_num-1 ) % KeysPerOctave] ==
							Piano::BlackKey &&
			_p.x() % PW_WHITE_KEY_WIDTH <=
					( PW_WHITE_KEY_WIDTH / 2 ) -
						( PW_BLACK_KEY_WIDTH / 2 ) )
		{
			--key_num;
		}
		if( key_num < NumKeys - 1 &&
			KEY_ORDER[( key_num + 1 ) % KeysPerOctave] ==
							Piano::BlackKey &&
			_p.x() % PW_WHITE_KEY_WIDTH >=
				( PW_WHITE_KEY_WIDTH -
				  		PW_BLACK_KEY_WIDTH / 2 ) )
		{
			++key_num;
		}
	}

	// some range-checking-stuff
	return tLimit( key_num, 0, NumKeys - 1 );
}
Example #3
0
void pluginDescWidget::paintEvent( QPaintEvent * )
{
	const QColor fill_color = m_mouseOver ? QColor( 224, 224, 224 ) :
						QColor( 192, 192, 192 );

	QPainter p( this );
	p.fillRect( rect(), fill_color );

	const int s = 16 + ( 32 * ( tLimit( height(), 24, 60 ) - 24 ) ) /
								( 60 - 24 );
	const QSize logo_size( s, s );
	QPixmap logo = m_logo.scaled( logo_size, Qt::KeepAspectRatio,
						Qt::SmoothTransformation );
	p.setPen( QColor( 64, 64, 64 ) );
	p.drawRect( 0, 0, rect().right(), rect().bottom() );
	p.drawPixmap( 4, 4, logo );

	QFont f = pointSize<8>( p.font() );
	f.setBold( true );
	p.setFont( f );
	p.drawText( 10 + logo_size.width(), 15,
					m_pluginDescriptor.displayName );

	if( height() > 24 || m_mouseOver )
	{
		f.setBold( false );
		p.setFont( pointSize<8>( f ) );
		QRect br;
		p.drawText( 10 + logo_size.width(), 20, width() - 58 - 5, 999,
							Qt::TextWordWrap,
			pluginBrowser::tr( m_pluginDescriptor.description ),
								&br );
		if( m_mouseOver )
		{
			m_targetHeight = qMax( 60, 25 + br.height() );
		}
	}

}
Example #4
0
void MidiClientRaw::processOutEvent( const midiEvent & _me,
							const midiTime & ,
							const MidiPort * _port )
{
	// TODO: also evaluate _time and queue event if necessary
	switch( _me.m_type )
	{
		case MidiNoteOn:
		case MidiNoteOff:
		case MidiKeyPressure:
			sendByte( _me.m_type | _me.channel() );
			sendByte( _me.m_data.m_param[0] + KeysPerOctave );
			sendByte( tLimit( (int) _me.m_data.m_param[1],
								0, 127 ) );
			break;

		default:
			qWarning( "MidiClientRaw: unhandled MIDI-event %d\n",
							(int) _me.m_type );
			break;
	}
}
Example #5
0
/*! \brief Turn a key on or off
 *
 *  \param _key the key number to change
 *  \param _on the state to set the key to
 */
void Piano::setKeyState( int _key, bool _on )
{
	m_pressedKeys[tLimit( _key, 0, NumKeys-1 )] = _on;
	emit dataChanged();
}
Example #6
0
sampleFrameA * Mixer::renderNextBuffer()
{
	MicroTimer timer;
	static song::playPos last_metro_pos = -1;

	FxMixer * fxm = engine::fxMixer();

	song::playPos p = engine::getSong()->getPlayPos( song::Mode_PlayPattern );
	if( engine::getSong()->playMode() == song::Mode_PlayPattern &&
		engine::getPianoRoll()->isRecording() == true &&
		p != last_metro_pos && p.getTicks() %
					(DefaultTicksPerTact / 4 ) == 0 )
	{
		addPlayHandle( new samplePlayHandle( "misc/metronome01.ogg" ) );
		last_metro_pos = p;
	}

	lockInputFrames();
	// swap buffer
	m_inputBufferWrite = ( m_inputBufferWrite + 1 ) % 2;
	m_inputBufferRead =  ( m_inputBufferRead + 1 ) % 2;
	// clear new write buffer
	m_inputBufferFrames[ m_inputBufferWrite ] = 0;
	unlockInputFrames();


	// now we have to make sure no other thread does anything bad
	// while we're acting...
	lock();

	// remove all play-handles that have to be deleted and delete
	// them if they still exist...
	// maybe this algorithm could be optimized...
	ConstPlayHandleList::Iterator it_rem = m_playHandlesToRemove.begin();
	while( it_rem != m_playHandlesToRemove.end() )
	{
		PlayHandleList::Iterator it = qFind( m_playHandles.begin(),
						m_playHandles.end(), *it_rem );

		if( it != m_playHandles.end() )
		{
			delete *it;
			m_playHandles.erase( it );
		}

		it_rem = m_playHandlesToRemove.erase( it_rem );
	}

	// rotate buffers
	m_writeBuffer = ( m_writeBuffer + 1 ) % m_poolDepth;
	m_readBuffer = ( m_readBuffer + 1 ) % m_poolDepth;

	m_writeBuf = m_bufferPool[m_writeBuffer];
	m_readBuf = m_bufferPool[m_readBuffer];

	// clear last audio-buffer
	clearAudioBuffer( m_writeBuf, m_framesPerPeriod );

	// prepare master mix (clear internal buffers etc.)
	fxm->prepareMasterMix();

	// create play-handles for new notes, samples etc.
	engine::getSong()->processNextBuffer();


	// STAGE 1: run and render all play handles
	MixerWorkerThread::fillJobQueue<PlayHandleList>( m_playHandles );
	MixerWorkerThread::startAndWaitForJobs();

	// removed all play handles which are done
	for( PlayHandleList::Iterator it = m_playHandles.begin();
						it != m_playHandles.end(); )
	{
		if( ( *it )->affinityMatters() &&
			( *it )->affinity() != QThread::currentThread() )
		{
			++it;
			continue;
		}
		if( ( *it )->done() )
		{
			delete *it;
			it = m_playHandles.erase( it );
		}
		else
		{
			++it;
		}
	}


	// STAGE 2: process effects of all instrument- and sampletracks
	MixerWorkerThread::fillJobQueue<QVector<AudioPort *> >( m_audioPorts );
	MixerWorkerThread::startAndWaitForJobs();

	// STAGE 3: do master mix in FX mixer
	fxm->masterMix( m_writeBuf );

	unlock();


	emit nextAudioBuffer();

	// and trigger LFOs
	EnvelopeAndLfoParameters::instances()->trigger();
	Controller::triggerFrameCounter();

	const float new_cpu_load = timer.elapsed() / 10000.0f *
				processingSampleRate() / m_framesPerPeriod;
	m_cpuLoad = tLimit( (int) ( new_cpu_load * 0.1f + m_cpuLoad * 0.9f ), 0,
									100 );

	return m_readBuf;
}