int Sampler::__render_note_resample( Sample *pSample, Note *pNote, int nBufferSize, int nInitialSilence, float cost_L, float cost_R, float cost_track_L, float cost_track_R, float fLayerPitch, Song* pSong ) { AudioOutput* audio_output = Hydrogen::get_instance()->getAudioOutput(); int nNoteLength = -1; if ( pNote->get_length() != -1 ) { nNoteLength = ( int )( pNote->get_length() * audio_output->m_transport.m_nTickSize ); } float fNotePitch = pNote->get_total_pitch() + fLayerPitch; float fStep = pow( 1.0594630943593, ( double )fNotePitch ); // _ERRORLOG( QString("pitch: %1, step: %2" ).arg(fNotePitch).arg( fStep) ); fStep *= ( float )pSample->get_sample_rate() / audio_output->getSampleRate(); // Adjust for audio driver sample rate // verifico il numero di frame disponibili ancora da eseguire int nAvail_bytes = ( int )( ( float )( pSample->get_frames() - pNote->get_sample_position() ) / fStep ); int retValue = 1; // the note is ended if ( nAvail_bytes > nBufferSize - nInitialSilence ) { // il sample e' piu' grande del buffersize // imposto il numero dei bytes disponibili uguale al buffersize nAvail_bytes = nBufferSize - nInitialSilence; retValue = 0; // the note is not ended yet } // ADSR *pADSR = pNote->m_pADSR; int nInitialBufferPos = nInitialSilence; float fInitialSamplePos = pNote->get_sample_position(); double fSamplePos = pNote->get_sample_position(); int nTimes = nInitialBufferPos + nAvail_bytes; int nInstrument = pSong->get_instrument_list()->index( pNote->get_instrument() ); float *pSample_data_L = pSample->get_data_l(); float *pSample_data_R = pSample->get_data_r(); float fInstrPeak_L = pNote->get_instrument()->get_peak_l(); // this value will be reset to 0 by the mixer.. float fInstrPeak_R = pNote->get_instrument()->get_peak_r(); // this value will be reset to 0 by the mixer.. float fADSRValue = 1.0; float fVal_L; float fVal_R; int nSampleFrames = pSample->get_frames(); /* * nInstrument could be -1 if the instrument is not found in the current drumset. * This happens when someone is using the prelistening function of the soundlibrary. */ if( nInstrument < 0 ) { nInstrument = 0; } #ifdef H2CORE_HAVE_JACK JackOutput* jao = 0; float *track_out_L = 0; float *track_out_R = 0; if( audio_output->has_track_outs() && (jao = dynamic_cast<JackOutput*>(audio_output)) ) { track_out_L = jao->getTrackOut_L( nInstrument ); track_out_R = jao->getTrackOut_R( nInstrument ); } #endif for ( int nBufferPos = nInitialBufferPos; nBufferPos < nTimes; ++nBufferPos ) { if ( ( nNoteLength != -1 ) && ( nNoteLength <= pNote->get_sample_position() ) ) { if ( pNote->get_adsr()->release() == 0 ) { retValue = 1; // the note is ended } } int nSamplePos = ( int )fSamplePos; double fDiff = fSamplePos - nSamplePos; if ( ( nSamplePos + 1 ) >= nSampleFrames ) { //we reach the last audioframe. //set this last frame to zero do nothin wrong. fVal_L = 0.0; fVal_R = 0.0; } else { // some interpolation methods need 4 frames data. float last_l; float last_r; if ( ( nSamplePos + 2 ) >= nSampleFrames ) { last_l = 0.0; last_r = 0.0; } else { last_l = pSample_data_L[nSamplePos + 2]; last_r = pSample_data_R[nSamplePos + 2]; } switch( __interpolateMode ){ case LINEAR: fVal_L = pSample_data_L[nSamplePos] * (1 - fDiff ) + pSample_data_L[nSamplePos + 1] * fDiff; fVal_R = pSample_data_R[nSamplePos] * (1 - fDiff ) + pSample_data_R[nSamplePos + 1] * fDiff; //fVal_L = linear_Interpolate( pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], fDiff); //fVal_R = linear_Interpolate( pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], fDiff); break; case COSINE: fVal_L = cosine_Interpolate( pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], fDiff); fVal_R = cosine_Interpolate( pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], fDiff); break; case THIRD: fVal_L = third_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff); fVal_R = third_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff); break; case CUBIC: fVal_L = cubic_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff); fVal_R = cubic_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff); break; case HERMITE: fVal_L = hermite_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff); fVal_R = hermite_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff); break; } } // ADSR envelope fADSRValue = pNote->get_adsr()->get_value( fStep ); fVal_L = fVal_L * fADSRValue; fVal_R = fVal_R * fADSRValue; // Low pass resonant filter if ( pNote->get_instrument()->is_filter_active() ) { pNote->compute_lr_values( &fVal_L, &fVal_R ); } #ifdef H2CORE_HAVE_JACK if( track_out_L ) { track_out_L[nBufferPos] += fVal_L * cost_track_L; } if( track_out_R ) { track_out_R[nBufferPos] += fVal_R * cost_track_R; } #endif fVal_L = fVal_L * cost_L; fVal_R = fVal_R * cost_R; // update instr peak if ( fVal_L > fInstrPeak_L ) { fInstrPeak_L = fVal_L; } if ( fVal_R > fInstrPeak_R ) { fInstrPeak_R = fVal_R; } // to main mix __main_out_L[nBufferPos] += fVal_L; __main_out_R[nBufferPos] += fVal_R; fSamplePos += fStep; } pNote->update_sample_position( nAvail_bytes * fStep ); pNote->get_instrument()->set_peak_l( fInstrPeak_L ); pNote->get_instrument()->set_peak_r( fInstrPeak_R ); #ifdef H2CORE_HAVE_LADSPA // LADSPA float masterVol = pSong->get_volume(); for ( unsigned nFX = 0; nFX < MAX_FX; ++nFX ) { LadspaFX *pFX = Effects::get_instance()->getLadspaFX( nFX ); float fLevel = pNote->get_instrument()->get_fx_level( nFX ); if ( ( pFX ) && ( fLevel != 0.0 ) ) { fLevel = fLevel * pFX->getVolume(); float *pBuf_L = pFX->m_pBuffer_L; float *pBuf_R = pFX->m_pBuffer_R; // float fFXCost_L = cost_L * fLevel; // float fFXCost_R = cost_R * fLevel; float fFXCost_L = fLevel * masterVol; float fFXCost_R = fLevel * masterVol; int nBufferPos = nInitialBufferPos; float fSamplePos = fInitialSamplePos; for ( int i = 0; i < nAvail_bytes; ++i ) { int nSamplePos = ( int )fSamplePos; double fDiff = fSamplePos - nSamplePos; if ( ( nSamplePos + 1 ) >= nSampleFrames ) { //we reach the last audioframe. //set this last frame to zero do nothin wrong. fVal_L = 0.0; fVal_R = 0.0; } else { // some interpolation methods need 4 frames data. float last_l; float last_r; if ( ( nSamplePos + 2 ) >= nSampleFrames ) { last_l = 0.0; last_r = 0.0; }else { last_l = pSample_data_L[nSamplePos + 2]; last_r = pSample_data_R[nSamplePos + 2]; } switch( __interpolateMode ){ case LINEAR: fVal_L = pSample_data_L[nSamplePos] * (1 - fDiff ) + pSample_data_L[nSamplePos + 1] * fDiff; fVal_R = pSample_data_R[nSamplePos] * (1 - fDiff ) + pSample_data_R[nSamplePos + 1] * fDiff; //fVal_L = linear_Interpolate( pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], fDiff); //fVal_R = linear_Interpolate( pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], fDiff); break; case COSINE: fVal_L = cosine_Interpolate( pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], fDiff); fVal_R = cosine_Interpolate( pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], fDiff); break; case THIRD: fVal_L = third_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff); fVal_R = third_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff); break; case CUBIC: fVal_L = cubic_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff); fVal_R = cubic_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff); break; case HERMITE: fVal_L = hermite_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff); fVal_R = hermite_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff); break; } // methode Interpolate produce an extra function call and eat much more time here. // so i deside to code the switch direct in the resampler methode //fVal_L = Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], pSample_data_L[nSamplePos + 2] ,fDiff); //fVal_L = Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], pSample_data_R[nSamplePos + 2] ,fDiff); } pBuf_L[ nBufferPos ] += fVal_L * fFXCost_L; pBuf_R[ nBufferPos ] += fVal_R * fFXCost_R; fSamplePos += fStep; ++nBufferPos; } } } #endif return retValue; }
int Sampler::__render_note_no_resample( Sample *pSample, Note *pNote, int nBufferSize, int nInitialSilence, float cost_L, float cost_R, float cost_track_L, float cost_track_R, Song* pSong ) { AudioOutput* audio_output = Hydrogen::get_instance()->getAudioOutput(); int retValue = 1; // the note is ended int nNoteLength = -1; if ( pNote->get_length() != -1 ) { nNoteLength = ( int )( pNote->get_length() * audio_output->m_transport.m_nTickSize ); } int nAvail_bytes = pSample->get_frames() - ( int )pNote->get_sample_position(); // verifico il numero di frame disponibili ancora da eseguire if ( nAvail_bytes > nBufferSize - nInitialSilence ) { // il sample e' piu' grande del buffersize // imposto il numero dei bytes disponibili uguale al buffersize nAvail_bytes = nBufferSize - nInitialSilence; retValue = 0; // the note is not ended yet } //ADSR *pADSR = pNote->m_pADSR; int nInitialBufferPos = nInitialSilence; int nInitialSamplePos = ( int )pNote->get_sample_position(); int nSamplePos = nInitialSamplePos; int nTimes = nInitialBufferPos + nAvail_bytes; int nInstrument = pSong->get_instrument_list()->index( pNote->get_instrument() ); float *pSample_data_L = pSample->get_data_l(); float *pSample_data_R = pSample->get_data_r(); float fInstrPeak_L = pNote->get_instrument()->get_peak_l(); // this value will be reset to 0 by the mixer.. float fInstrPeak_R = pNote->get_instrument()->get_peak_r(); // this value will be reset to 0 by the mixer.. float fADSRValue; float fVal_L; float fVal_R; /* * nInstrument could be -1 if the instrument is not found in the current drumset. * This happens when someone is using the prelistening function of the soundlibrary. */ if( nInstrument < 0 ) { nInstrument = 0; } #ifdef H2CORE_HAVE_JACK JackOutput* jao = 0; float *track_out_L = 0; float *track_out_R = 0; if( audio_output->has_track_outs() && (jao = dynamic_cast<JackOutput*>(audio_output)) ) { track_out_L = jao->getTrackOut_L( nInstrument ); track_out_R = jao->getTrackOut_R( nInstrument ); } #endif for ( int nBufferPos = nInitialBufferPos; nBufferPos < nTimes; ++nBufferPos ) { if ( ( nNoteLength != -1 ) && ( nNoteLength <= pNote->get_sample_position() ) ) { if ( pNote->get_adsr()->release() == 0 ) { retValue = 1; // the note is ended } } fADSRValue = pNote->get_adsr()->get_value( 1 ); fVal_L = pSample_data_L[ nSamplePos ] * fADSRValue; fVal_R = pSample_data_R[ nSamplePos ] * fADSRValue; // Low pass resonant filter if ( pNote->get_instrument()->is_filter_active() ) { pNote->compute_lr_values( &fVal_L, &fVal_R ); } #ifdef H2CORE_HAVE_JACK if( track_out_L ) { track_out_L[nBufferPos] += fVal_L * cost_track_L; } if( track_out_R ) { track_out_R[nBufferPos] += fVal_R * cost_track_R; } #endif fVal_L = fVal_L * cost_L; fVal_R = fVal_R * cost_R; // update instr peak if ( fVal_L > fInstrPeak_L ) { fInstrPeak_L = fVal_L; } if ( fVal_R > fInstrPeak_R ) { fInstrPeak_R = fVal_R; } // to main mix __main_out_L[nBufferPos] += fVal_L; __main_out_R[nBufferPos] += fVal_R; ++nSamplePos; } pNote->update_sample_position( nAvail_bytes ); pNote->get_instrument()->set_peak_l( fInstrPeak_L ); pNote->get_instrument()->set_peak_r( fInstrPeak_R ); #ifdef H2CORE_HAVE_LADSPA float masterVol = pSong->get_volume(); // LADSPA for ( unsigned nFX = 0; nFX < MAX_FX; ++nFX ) { LadspaFX *pFX = Effects::get_instance()->getLadspaFX( nFX ); float fLevel = pNote->get_instrument()->get_fx_level( nFX ); if ( ( pFX ) && ( fLevel != 0.0 ) ) { fLevel = fLevel * pFX->getVolume(); float *pBuf_L = pFX->m_pBuffer_L; float *pBuf_R = pFX->m_pBuffer_R; // float fFXCost_L = cost_L * fLevel; // float fFXCost_R = cost_R * fLevel; float fFXCost_L = fLevel * masterVol; float fFXCost_R = fLevel * masterVol; int nBufferPos = nInitialBufferPos; int nSamplePos = nInitialSamplePos; for ( int i = 0; i < nAvail_bytes; ++i ) { pBuf_L[ nBufferPos ] += pSample_data_L[ nSamplePos ] * fFXCost_L; pBuf_R[ nBufferPos ] += pSample_data_R[ nSamplePos ] * fFXCost_R; ++nSamplePos; ++nBufferPos; } } } // ~LADSPA #endif return retValue; }
bool Sampler::__render_note_no_resample( Sample *pSample, Note *pNote, SelectedLayerInfo *pSelectedLayerInfo, InstrumentComponent *pCompo, DrumkitComponent *pDrumCompo, int nBufferSize, int nInitialSilence, float cost_L, float cost_R, float cost_track_L, float cost_track_R, Song* pSong ) { AudioOutput* pAudioOutput = Hydrogen::get_instance()->getAudioOutput(); bool retValue = true; // the note is ended int nNoteLength = -1; if ( pNote->get_length() != -1 ) { nNoteLength = ( int )( pNote->get_length() * pAudioOutput->m_transport.m_nTickSize ); } int nAvail_bytes = pSample->get_frames() - ( int )pSelectedLayerInfo->SamplePosition; // verifico il numero di frame disponibili ancora da eseguire if ( nAvail_bytes > nBufferSize - nInitialSilence ) { // il sample e' piu' grande del buffersize // imposto il numero dei bytes disponibili uguale al buffersize nAvail_bytes = nBufferSize - nInitialSilence; retValue = false; // the note is not ended yet } //ADSR *pADSR = pNote->m_pADSR; int nInitialBufferPos = nInitialSilence; int nInitialSamplePos = ( int )pSelectedLayerInfo->SamplePosition; int nSamplePos = nInitialSamplePos; int nTimes = nInitialBufferPos + nAvail_bytes; float *pSample_data_L = pSample->get_data_l(); float *pSample_data_R = pSample->get_data_r(); float fInstrPeak_L = pNote->get_instrument()->get_peak_l(); // this value will be reset to 0 by the mixer.. float fInstrPeak_R = pNote->get_instrument()->get_peak_r(); // this value will be reset to 0 by the mixer.. float fADSRValue; float fVal_L; float fVal_R; #ifdef H2CORE_HAVE_JACK JackAudioDriver* pJackAudioDriver = 0; float * pTrackOutL = 0; float * pTrackOutR = 0; if( pAudioOutput->has_track_outs() && (pJackAudioDriver = dynamic_cast<JackAudioDriver*>(pAudioOutput)) ) { pTrackOutL = pJackAudioDriver->getTrackOut_L( pNote->get_instrument(), pCompo ); pTrackOutR = pJackAudioDriver->getTrackOut_R( pNote->get_instrument(), pCompo ); } #endif for ( int nBufferPos = nInitialBufferPos; nBufferPos < nTimes; ++nBufferPos ) { if ( ( nNoteLength != -1 ) && ( nNoteLength <= pSelectedLayerInfo->SamplePosition ) ) { if ( pNote->get_adsr()->release() == 0 ) { retValue = true; // the note is ended } } fADSRValue = pNote->get_adsr()->get_value( 1 ); fVal_L = pSample_data_L[ nSamplePos ] * fADSRValue; fVal_R = pSample_data_R[ nSamplePos ] * fADSRValue; // Low pass resonant filter if ( pNote->get_instrument()->is_filter_active() ) { pNote->compute_lr_values( &fVal_L, &fVal_R ); } #ifdef H2CORE_HAVE_JACK if( pTrackOutL ) { pTrackOutL[nBufferPos] += fVal_L * cost_track_L; } if( pTrackOutR ) { pTrackOutR[nBufferPos] += fVal_R * cost_track_R; } #endif fVal_L = fVal_L * cost_L; fVal_R = fVal_R * cost_R; // update instr peak if ( fVal_L > fInstrPeak_L ) { fInstrPeak_L = fVal_L; } if ( fVal_R > fInstrPeak_R ) { fInstrPeak_R = fVal_R; } pDrumCompo->set_outs( nBufferPos, fVal_L, fVal_R ); // to main mix __main_out_L[nBufferPos] += fVal_L; __main_out_R[nBufferPos] += fVal_R; ++nSamplePos; } pSelectedLayerInfo->SamplePosition += nAvail_bytes; pNote->get_instrument()->set_peak_l( fInstrPeak_L ); pNote->get_instrument()->set_peak_r( fInstrPeak_R ); #ifdef H2CORE_HAVE_LADSPA // LADSPA // change the below return logic if you add code after that ifdef if (pNote->get_instrument()->is_muted() || pSong->__is_muted) return retValue; float masterVol = pSong->get_volume(); for ( unsigned nFX = 0; nFX < MAX_FX; ++nFX ) { LadspaFX *pFX = Effects::get_instance()->getLadspaFX( nFX ); float fLevel = pNote->get_instrument()->get_fx_level( nFX ); if ( ( pFX ) && ( fLevel != 0.0 ) ) { fLevel = fLevel * pFX->getVolume(); float *pBuf_L = pFX->m_pBuffer_L; float *pBuf_R = pFX->m_pBuffer_R; float fFXCost_L = fLevel * masterVol; float fFXCost_R = fLevel * masterVol; int nBufferPos = nInitialBufferPos; int nSamplePos = nInitialSamplePos; for ( int i = 0; i < nAvail_bytes; ++i ) { pBuf_L[ nBufferPos ] += pSample_data_L[ nSamplePos ] * fFXCost_L; pBuf_R[ nBufferPos ] += pSample_data_R[ nSamplePos ] * fFXCost_R; ++nSamplePos; ++nBufferPos; } } } // ~LADSPA #endif return retValue; }
bool Sampler::__render_note_resample( Sample *pSample, Note *pNote, SelectedLayerInfo *pSelectedLayerInfo, InstrumentComponent *pCompo, DrumkitComponent *pDrumCompo, int nBufferSize, int nInitialSilence, float cost_L, float cost_R, float cost_track_L, float cost_track_R, float fLayerPitch, Song* pSong ) { AudioOutput* pAudioOutput = Hydrogen::get_instance()->getAudioOutput(); int nNoteLength = -1; if ( pNote->get_length() != -1 ) { nNoteLength = ( int )( pNote->get_length() * pAudioOutput->m_transport.m_nTickSize ); } float fNotePitch = pNote->get_total_pitch() + fLayerPitch; float fStep = pow( 1.0594630943593, ( double )fNotePitch ); // _ERRORLOG( QString("pitch: %1, step: %2" ).arg(fNotePitch).arg( fStep) ); fStep *= ( float )pSample->get_sample_rate() / pAudioOutput->getSampleRate(); // Adjust for audio driver sample rate // verifico il numero di frame disponibili ancora da eseguire int nAvail_bytes = ( int )( ( float )( pSample->get_frames() - pSelectedLayerInfo->SamplePosition ) / fStep ); bool retValue = true; // the note is ended if ( nAvail_bytes > nBufferSize - nInitialSilence ) { // il sample e' piu' grande del buffersize // imposto il numero dei bytes disponibili uguale al buffersize nAvail_bytes = nBufferSize - nInitialSilence; retValue = false; // the note is not ended yet } // ADSR *pADSR = pNote->m_pADSR; int nInitialBufferPos = nInitialSilence; //float fInitialSamplePos = pNote->get_sample_position( pCompo->get_drumkit_componentID() ); double fSamplePos = pSelectedLayerInfo->SamplePosition; int nTimes = nInitialBufferPos + nAvail_bytes; float *pSample_data_L = pSample->get_data_l(); float *pSample_data_R = pSample->get_data_r(); float fInstrPeak_L = pNote->get_instrument()->get_peak_l(); // this value will be reset to 0 by the mixer.. float fInstrPeak_R = pNote->get_instrument()->get_peak_r(); // this value will be reset to 0 by the mixer.. float fADSRValue = 1.0; float fVal_L; float fVal_R; int nSampleFrames = pSample->get_frames(); #ifdef H2CORE_HAVE_JACK JackAudioDriver* pJackAudioDriver = 0; float * pTrackOutL = 0; float * pTrackOutR = 0; if( pAudioOutput->has_track_outs() && (pJackAudioDriver = dynamic_cast<JackAudioDriver*>(pAudioOutput)) ) { pTrackOutL = pJackAudioDriver->getTrackOut_L( pNote->get_instrument(), pCompo ); pTrackOutR = pJackAudioDriver->getTrackOut_R( pNote->get_instrument(), pCompo ); } #endif for ( int nBufferPos = nInitialBufferPos; nBufferPos < nTimes; ++nBufferPos ) { if ( ( nNoteLength != -1 ) && ( nNoteLength <= pSelectedLayerInfo->SamplePosition ) ) { if ( pNote->get_adsr()->release() == 0 ) { retValue = 1; // the note is ended } } int nSamplePos = ( int )fSamplePos; double fDiff = fSamplePos - nSamplePos; if ( ( nSamplePos + 1 ) >= nSampleFrames ) { //we reach the last audioframe. //set this last frame to zero do nothin wrong. fVal_L = 0.0; fVal_R = 0.0; } else { // some interpolation methods need 4 frames data. float last_l; float last_r; if ( ( nSamplePos + 2 ) >= nSampleFrames ) { last_l = 0.0; last_r = 0.0; } else { last_l = pSample_data_L[nSamplePos + 2]; last_r = pSample_data_R[nSamplePos + 2]; } switch( __interpolateMode ){ case LINEAR: fVal_L = pSample_data_L[nSamplePos] * (1 - fDiff ) + pSample_data_L[nSamplePos + 1] * fDiff; fVal_R = pSample_data_R[nSamplePos] * (1 - fDiff ) + pSample_data_R[nSamplePos + 1] * fDiff; //fVal_L = linear_Interpolate( pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], fDiff); //fVal_R = linear_Interpolate( pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], fDiff); break; case COSINE: fVal_L = cosine_Interpolate( pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], fDiff); fVal_R = cosine_Interpolate( pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], fDiff); break; case THIRD: fVal_L = third_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff); fVal_R = third_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff); break; case CUBIC: fVal_L = cubic_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff); fVal_R = cubic_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff); break; case HERMITE: fVal_L = hermite_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff); fVal_R = hermite_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff); break; } } // ADSR envelope fADSRValue = pNote->get_adsr()->get_value( fStep ); fVal_L = fVal_L * fADSRValue; fVal_R = fVal_R * fADSRValue; // Low pass resonant filter if ( pNote->get_instrument()->is_filter_active() ) { pNote->compute_lr_values( &fVal_L, &fVal_R ); } #ifdef H2CORE_HAVE_JACK if( pTrackOutL ) { pTrackOutL[nBufferPos] += fVal_L * cost_track_L; } if( pTrackOutR ) { pTrackOutR[nBufferPos] += fVal_R * cost_track_R; } #endif fVal_L = fVal_L * cost_L; fVal_R = fVal_R * cost_R; // update instr peak if ( fVal_L > fInstrPeak_L ) { fInstrPeak_L = fVal_L; } if ( fVal_R > fInstrPeak_R ) { fInstrPeak_R = fVal_R; } pDrumCompo->set_outs( nBufferPos, fVal_L, fVal_R ); // to main mix __main_out_L[nBufferPos] += fVal_L; __main_out_R[nBufferPos] += fVal_R; fSamplePos += fStep; } pSelectedLayerInfo->SamplePosition += nAvail_bytes * fStep; pNote->get_instrument()->set_peak_l( fInstrPeak_L ); pNote->get_instrument()->set_peak_r( fInstrPeak_R ); #ifdef H2CORE_HAVE_LADSPA // LADSPA // change the below return logic if you add code after that ifdef if (pNote->get_instrument()->is_muted() || pSong->__is_muted) return retValue; float masterVol = pSong->get_volume(); for ( unsigned nFX = 0; nFX < MAX_FX; ++nFX ) { LadspaFX *pFX = Effects::get_instance()->getLadspaFX( nFX ); float fLevel = pNote->get_instrument()->get_fx_level( nFX ); if ( ( pFX ) && ( fLevel != 0.0 ) ) { fLevel = fLevel * pFX->getVolume(); float *pBuf_L = pFX->m_pBuffer_L; float *pBuf_R = pFX->m_pBuffer_R; // float fFXCost_L = cost_L * fLevel; // float fFXCost_R = cost_R * fLevel; float fFXCost_L = fLevel * masterVol; float fFXCost_R = fLevel * masterVol; int nBufferPos = nInitialBufferPos; float fSamplePos = pSelectedLayerInfo->SamplePosition; for ( int i = 0; i < nAvail_bytes; ++i ) { int nSamplePos = ( int )fSamplePos; double fDiff = fSamplePos - nSamplePos; if ( ( nSamplePos + 1 ) >= nSampleFrames ) { //we reach the last audioframe. //set this last frame to zero do nothin wrong. fVal_L = 0.0; fVal_R = 0.0; } else { // some interpolation methods need 4 frames data. float last_l; float last_r; if ( ( nSamplePos + 2 ) >= nSampleFrames ) { last_l = 0.0; last_r = 0.0; }else { last_l = pSample_data_L[nSamplePos + 2]; last_r = pSample_data_R[nSamplePos + 2]; } switch( __interpolateMode ){ case LINEAR: fVal_L = pSample_data_L[nSamplePos] * (1 - fDiff ) + pSample_data_L[nSamplePos + 1] * fDiff; fVal_R = pSample_data_R[nSamplePos] * (1 - fDiff ) + pSample_data_R[nSamplePos + 1] * fDiff; break; case COSINE: fVal_L = cosine_Interpolate( pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], fDiff); fVal_R = cosine_Interpolate( pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], fDiff); break; case THIRD: fVal_L = third_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff); fVal_R = third_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff); break; case CUBIC: fVal_L = cubic_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff); fVal_R = cubic_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff); break; case HERMITE: fVal_L = hermite_Interpolate( pSample_data_L[ nSamplePos -1], pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], last_l, fDiff); fVal_R = hermite_Interpolate( pSample_data_R[ nSamplePos -1], pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], last_r, fDiff); break; } } pBuf_L[ nBufferPos ] += fVal_L * fFXCost_L; pBuf_R[ nBufferPos ] += fVal_R * fFXCost_R; fSamplePos += fStep; ++nBufferPos; } } } #endif return retValue; }
void Mixer::updateMixer() { Preferences *pPref = Preferences::get_instance(); bool bShowPeaks = pPref->showInstrumentPeaks(); Hydrogen *pEngine = Hydrogen::get_instance(); Song *pSong = pEngine->getSong(); InstrumentList *pInstrList = pSong->get_instrument_list(); std::vector<DrumkitComponent*>* compoList = pSong->get_components(); uint nSelectedInstr = pEngine->getSelectedInstrumentNumber(); float fallOff = pPref->getMixerFalloffSpeed(); uint nMuteClicked = 0; int nInstruments = pInstrList->size(); int nCompo = compoList->size(); for ( unsigned nInstr = 0; nInstr < MAX_INSTRUMENTS; ++nInstr ) { if ( nInstr >= nInstruments ) { // unused instrument! let's hide and destroy the mixerline! if ( m_pMixerLine[ nInstr ] ) { delete m_pMixerLine[ nInstr ]; m_pMixerLine[ nInstr ] = NULL; int newWidth = MIXER_STRIP_WIDTH * ( nInstruments + nCompo ); if ( m_pFaderPanel->width() != newWidth ) { m_pFaderPanel->resize( newWidth, height() ); } } continue; } else { if ( m_pMixerLine[ nInstr ] == NULL ) { // the mixerline doesn't exists..I'll create a new one! m_pMixerLine[ nInstr ] = createMixerLine( nInstr ); m_pFaderHBox->insertWidget( nInstr, m_pMixerLine[ nInstr ] ); int newWidth = MIXER_STRIP_WIDTH * ( nInstruments + nCompo ); if ( m_pFaderPanel->width() != newWidth ) { m_pFaderPanel->resize( newWidth, height() ); } } MixerLine *pLine = m_pMixerLine[ nInstr ]; Instrument *pInstr = pInstrList->get( nInstr ); assert( pInstr ); float fNewPeak_L = pInstr->get_peak_l(); pInstr->set_peak_l( 0.0f ); // reset instrument peak float fNewPeak_R = pInstr->get_peak_r(); pInstr->set_peak_r( 0.0f ); // reset instrument peak float fNewVolume = pInstr->get_volume(); bool bMuted = pInstr->is_muted(); QString sName = pInstr->get_name(); float fPan_L = pInstr->get_pan_l(); float fPan_R = pInstr->get_pan_r(); // fader float fOldPeak_L = pLine->getPeak_L(); float fOldPeak_R = pLine->getPeak_R(); if (!bShowPeaks) { fNewPeak_L = 0.0f; fNewPeak_R = 0.0f; } if ( fNewPeak_L >= fOldPeak_L) { // LEFT peak pLine->setPeak_L( fNewPeak_L ); } else { pLine->setPeak_L( fOldPeak_L / fallOff ); } if ( fNewPeak_R >= fOldPeak_R) { // Right peak pLine->setPeak_R( fNewPeak_R ); } else { pLine->setPeak_R( fOldPeak_R / fallOff ); } // fader position pLine->setVolume( fNewVolume ); // mute if ( bMuted ) { nMuteClicked++; } pLine->setMuteClicked( bMuted ); // instr name pLine->setName( sName ); // pan float fPanValue = 0.0; if (fPan_R == 1.0) { fPanValue = 1.0 - (fPan_L / 2.0); } else { fPanValue = fPan_R / 2.0; } pLine->setPan( fPanValue ); // activity if ( pLine->getActivity() > 0 ) { pLine->setActivity( m_pMixerLine[ nInstr ]->getActivity() - 30 ); pLine->setPlayClicked( true ); } else { pLine->setPlayClicked( false ); } for (uint nFX = 0; nFX < MAX_FX; nFX++) { pLine->setFXLevel( nFX, pInstr->get_fx_level( nFX ) ); } pLine->setSelected( nInstr == nSelectedInstr ); pLine->updateMixerLine(); } } for (std::vector<DrumkitComponent*>::iterator it = compoList->begin() ; it != compoList->end(); ++it) { DrumkitComponent* p_compo = *it; if( m_pComponentMixerLine.find(p_compo->get_id()) == m_pComponentMixerLine.end() ) { // the mixerline doesn't exists..I'll create a new one! m_pComponentMixerLine[ p_compo->get_id() ] = createComponentMixerLine( p_compo->get_id() ); m_pFaderHBox->addWidget( m_pComponentMixerLine[ p_compo->get_id() ] ); int newWidth = MIXER_STRIP_WIDTH * ( nInstruments + nCompo ); if ( m_pFaderPanel->width() != newWidth ) { m_pFaderPanel->resize( newWidth, height() ); } } ComponentMixerLine *pLine = m_pComponentMixerLine[ p_compo->get_id() ]; float fNewPeak_L = p_compo->get_peak_l(); p_compo->set_peak_l( 0.0f ); // reset instrument peak float fNewPeak_R = p_compo->get_peak_r(); p_compo->set_peak_r( 0.0f ); // reset instrument peak float fNewVolume = p_compo->get_volume(); bool bMuted = p_compo->is_muted(); QString sName = p_compo->get_name(); float fOldPeak_L = pLine->getPeak_L(); float fOldPeak_R = pLine->getPeak_R(); if (!bShowPeaks) { fNewPeak_L = 0.0f; fNewPeak_R = 0.0f; } if ( fNewPeak_L >= fOldPeak_L) { // LEFT peak pLine->setPeak_L( fNewPeak_L ); } else { pLine->setPeak_L( fOldPeak_L / fallOff ); } if ( fNewPeak_R >= fOldPeak_R) { // Right peak pLine->setPeak_R( fNewPeak_R ); } else { pLine->setPeak_R( fOldPeak_R / fallOff ); } // fader position pLine->setVolume( fNewVolume ); // mute if ( bMuted ) { nMuteClicked++; } pLine->setMuteClicked( bMuted ); // instr name pLine->setName( sName ); pLine->updateMixerLine(); } if( compoList->size() < m_pComponentMixerLine.size() ) { std::vector<int>* p_ids_to_delete = new std::vector<int>(); for (std::map<int, ComponentMixerLine*>::iterator it=m_pComponentMixerLine.begin(); it!=m_pComponentMixerLine.end(); ++it) { bool p_foundExistingRelatedComponent = false; for ( std::vector<DrumkitComponent*>::iterator it2 = compoList->begin() ; it2 != compoList->end(); ++it2 ) { DrumkitComponent* p_compo = *it2; if( p_compo->get_id() == it->first ) { p_foundExistingRelatedComponent = true; break; } } if( !p_foundExistingRelatedComponent ) p_ids_to_delete->push_back( it->first ) ; } for ( std::vector<int>::iterator it = p_ids_to_delete->begin() ; it != p_ids_to_delete->end(); ++it ) { int p_compoID = *it; delete m_pComponentMixerLine[p_compoID]; m_pComponentMixerLine.erase( p_compoID ); int newWidth = MIXER_STRIP_WIDTH * ( nInstruments + nCompo ); if ( m_pFaderPanel->width() != newWidth ) { m_pFaderPanel->resize( newWidth, height() ); } } } if (nMuteClicked == nInstruments - 1) { // find the not muted button for (uint i = 0; i < nInstruments; i++) { Instrument *instr = pInstrList->get(i); if (instr->is_muted() == false) { m_pMixerLine[i]->setSoloClicked(true); break; } } } else { for (uint i = 0; i < nInstruments; i++) { m_pMixerLine[i]->setSoloClicked(false); } } // update MasterPeak float oldPeak_L = m_pMasterLine->getPeak_L(); float newPeak_L = pEngine->getMasterPeak_L(); pEngine->setMasterPeak_L(0.0); float oldPeak_R = m_pMasterLine->getPeak_R(); float newPeak_R = pEngine->getMasterPeak_R(); pEngine->setMasterPeak_R(0.0); if (!bShowPeaks) { newPeak_L = 0.0; newPeak_R = 0.0; } if (newPeak_L >= oldPeak_L) { m_pMasterLine->setPeak_L( newPeak_L ); } else { m_pMasterLine->setPeak_L( oldPeak_L / fallOff ); } if (newPeak_R >= oldPeak_R) { m_pMasterLine->setPeak_R(newPeak_R); } else { m_pMasterLine->setPeak_R( oldPeak_R / fallOff ); } // set master fader position float newVolume = pSong->get_volume(); float oldVolume = m_pMasterLine->getVolume(); if (oldVolume != newVolume) { m_pMasterLine->setVolume(newVolume); } m_pMasterLine->updateMixerLine(); #ifdef H2CORE_HAVE_LADSPA // LADSPA for (uint nFX = 0; nFX < MAX_FX; nFX++) { LadspaFX *pFX = Effects::get_instance()->getLadspaFX( nFX ); if ( pFX ) { m_pLadspaFXLine[nFX]->setName( pFX->getPluginName() ); float fNewPeak_L = 0.0; float fNewPeak_R = 0.0; float fOldPeak_L = 0.0; float fOldPeak_R = 0.0; m_pLadspaFXLine[nFX]->getPeaks( &fOldPeak_L, &fOldPeak_R ); if (fNewPeak_L < fOldPeak_L) fNewPeak_L = fOldPeak_L / fallOff; if (fNewPeak_R < fOldPeak_R) fNewPeak_R = fOldPeak_R / fallOff; m_pLadspaFXLine[nFX]->setPeaks( fNewPeak_L, fNewPeak_R ); m_pLadspaFXLine[nFX]->setFxActive( pFX->isEnabled() ); m_pLadspaFXLine[nFX]->setVolume( pFX->getVolume() ); } else { m_pLadspaFXLine[nFX]->setName( "No plugin" ); m_pLadspaFXLine[nFX]->setFxActive( false ); m_pLadspaFXLine[nFX]->setVolume( 0.0 ); } } // ~LADSPA #endif }