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; }
/*! \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 ); }
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() ); } } }
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; } }
/*! \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(); }
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; }