Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work In Progress: Probability 2.0 #525

Open
wants to merge 13 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified data/img/gray/mixerPanel/masterMixerline_background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/core/AudioEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,8 @@ inline void AudioEngine::processPlayNotes( unsigned long nframes )
*/
float fNoteProbability = pNote->get_probability();
if ( fNoteProbability != 1. ) {
if ( fNoteProbability < (float) rand() / (float) RAND_MAX ) {
float fThreshold = pSong->getThreshold();
if ( fNoteProbability < fThreshold ) {
m_songNoteQueue.pop();
pNote->get_instrument()->dequeue();
continue;
Expand Down
18 changes: 18 additions & 0 deletions src/core/Basics/Song.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ Song::Song( const QString& sName, const QString& sAuthor, float fBpm, float fVol
, m_actionMode( ActionMode::selectMode )
, m_nPanLawType ( Sampler::RATIO_STRAIGHT_POLYGONAL )
, m_fPanLawKNorm ( Sampler::K_NORM_DEFAULT )
, m_fFillValue( 0.5 )
, m_fFillRandomize( 0 )
{
INFOLOG( QString( "INIT '%1'" ).arg( sName ) );

Expand Down Expand Up @@ -842,6 +844,8 @@ std::shared_ptr<Song> SongReader::readSong( const QString& sFileName )
float fHumanizeTimeValue = LocalFileMng::readXmlFloat( songNode, "humanize_time", 0.0 );
float fHumanizeVelocityValue = LocalFileMng::readXmlFloat( songNode, "humanize_velocity", 0.0 );
float fSwingFactor = LocalFileMng::readXmlFloat( songNode, "swing_factor", 0.0 );
float fFillValue = LocalFileMng::readXmlFloat( songNode, "fillValue", 0.5 );
float fFillRandomize = LocalFileMng::readXmlFloat( songNode, "fillRandomize", 1.0 );

pSong = std::make_shared<Song>( sName, sAuthor, fBpm, fVolume );
pSong->setMetronomeVolume( fMetronomeVolume );
Expand All @@ -855,6 +859,8 @@ std::shared_ptr<Song> SongReader::readSong( const QString& sFileName )
pSong->setPlaybackTrackFilename( sPlaybackTrack );
pSong->setPlaybackTrackEnabled( bPlaybackTrackEnabled );
pSong->setPlaybackTrackVolume( fPlaybackTrackVolume );
pSong->setFillValue( fFillValue );
pSong->setFillRandomize( fFillRandomize );
pSong->setActionMode( actionMode );

// pan law
Expand Down Expand Up @@ -1641,4 +1647,16 @@ Pattern* SongReader::getPattern( QDomNode pattern, InstrumentList* pInstrList )

return pPattern;
}


float Song::getThreshold() const
{
float w = getFillRandomize();
float k = 1.0f - w;
float lower = getFillValue() * k;
float upper = lower + w;
float rnd = (float)rand()/(float)RAND_MAX;
return 1.0f - (lower + rnd * (upper-lower));
}

};
30 changes: 30 additions & 0 deletions src/core/Basics/Song.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,13 @@ class Song : public H2Core::Object, public std::enable_shared_from_this<Song>
/** \param volume Sets #m_fPlaybackTrackVolume. */
void setPlaybackTrackVolume( const float fVolume );

float getFillValue() const;
void setFillValue( float fFillValue );
float getFillRandomize() const;
void setFillRandomize( float fFillRandomize );

float getThreshold() const;

/** Defines the type of user interaction experienced in the
SongEditor.*/
enum class ActionMode {
Expand Down Expand Up @@ -291,6 +298,9 @@ class Song : public H2Core::Object, public std::enable_shared_from_this<Song>

/** Stores the type of interaction with the SongEditor. */
ActionMode m_actionMode;

float m_fFillValue;
float m_fFillRandomize;

int m_nPanLawType;
// k such that L^k+R^k = 1. Used in constant k-Norm pan law
Expand Down Expand Up @@ -550,6 +560,26 @@ inline float Song::getPanLawKNorm() const {
return m_fPanLawKNorm;
}

inline float Song::getFillValue() const
{
return m_fFillValue;
}

inline void Song::setFillValue( float fFillValue )
{
m_fFillValue = fFillValue;
}

inline float Song::getFillRandomize() const
{
return m_fFillRandomize;
}

inline void Song::setFillRandomize( float fFillRandomize )
{
m_fFillRandomize = fFillRandomize;
}

/**
\ingroup H2CORE
\brief Read XML file of a song
Expand Down
2 changes: 2 additions & 0 deletions src/core/LocalFileMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,8 @@ int SongWriter::writeSong( std::shared_ptr<Song> pSong, const QString& filename
LocalFileMng::writeXmlString( songNode, "humanize_time", QString("%1").arg( pSong->getHumanizeTimeValue() ) );
LocalFileMng::writeXmlString( songNode, "humanize_velocity", QString("%1").arg( pSong->getHumanizeVelocityValue() ) );
LocalFileMng::writeXmlString( songNode, "swing_factor", QString("%1").arg( pSong->getSwingFactor() ) );
LocalFileMng::writeXmlString( songNode, "fillValue", QString("%1").arg( pSong->getFillValue() ) );
LocalFileMng::writeXmlString( songNode, "fillRandomize", QString("%1").arg( pSong->getFillRandomize() ) );

// component List
QDomNode componentListNode = doc.createElement( "componentList" );
Expand Down
58 changes: 57 additions & 1 deletion src/core/MidiAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,13 @@ MidiActionManager::MidiActionManager() : Object( __class_name ) {
actionMap.insert(std::make_pair("MASTER_VOLUME_ABSOLUTE", std::make_pair(&MidiActionManager::master_volume_absolute, empty)));
actionMap.insert(std::make_pair("STRIP_VOLUME_RELATIVE", std::make_pair(&MidiActionManager::strip_volume_relative, empty)));
actionMap.insert(std::make_pair("STRIP_VOLUME_ABSOLUTE", std::make_pair(&MidiActionManager::strip_volume_absolute, empty)));


actionMap.insert(std::make_pair("HUMANIZE_VELOCITY_ABSOLUTE", std::make_pair(&MidiActionManager::humanize_velocity_absolute, empty)));
actionMap.insert(std::make_pair("HUMANIZE_TIME_ABSOLUTE", std::make_pair(&MidiActionManager::humanize_time_absolute, empty)));
actionMap.insert(std::make_pair("SWING_ABSOLUTE", std::make_pair(&MidiActionManager::swing_absolute, empty)));
actionMap.insert(std::make_pair("FILL_VALUE_ABSOLUTE", std::make_pair(&MidiActionManager::fill_value_absolute, empty)));
actionMap.insert(std::make_pair("FILL_RANDOMIZE_ABSOLUTE", std::make_pair(&MidiActionManager::fill_randomize_absolute, empty)));

for(int i = 0; i < MAX_FX; ++i) {
targeted_element effect = {i,0};
std::ostringstream toChar;
Expand Down Expand Up @@ -809,6 +815,56 @@ bool MidiActionManager::bpm_fine_cc_relative(Action * pAction, Hydrogen* pHydrog
return true;
}

bool MidiActionManager::humanize_velocity_absolute(Action * pAction, Hydrogen* pHydrogen , targeted_element ) {
bool ok;
int value = pAction->getParameter2().toInt(&ok,10);

std::shared_ptr<Song> pSong = pHydrogen->getSong();
pSong->setHumanizeVelocityValue( value / 127.0 );

return true;
}

bool MidiActionManager::humanize_time_absolute(Action *pAction , Hydrogen* pHydrogen , targeted_element ) {
bool ok;
int value = pAction->getParameter2().toInt(&ok,10);

std::shared_ptr<Song> pSong = pHydrogen->getSong();
pSong->setHumanizeTimeValue( value / 127.0 );

return true;
}

bool MidiActionManager::swing_absolute(Action *pAction , Hydrogen* pHydrogen , targeted_element ) {
bool ok;
int value = pAction->getParameter2().toInt(&ok,10);

std::shared_ptr<Song> pSong = pHydrogen->getSong();
pSong->setSwingFactor( value / 127.0 );

return true;
}

bool MidiActionManager::fill_value_absolute(Action *pAction , Hydrogen* pHydrogen , targeted_element ) {
bool ok;
int value = pAction->getParameter2().toInt(&ok,10);

std::shared_ptr<Song> pSong = pHydrogen->getSong();
pSong->setFillValue( value / 127.0 );

return true;
}

bool MidiActionManager::fill_randomize_absolute(Action *pAction , Hydrogen* pHydrogen , targeted_element ) {
bool ok;
int value = pAction->getParameter2().toInt(&ok,10);

std::shared_ptr<Song> pSong = pHydrogen->getSong();
pSong->setFillRandomize( value / 127.0 );

return true;
}

bool MidiActionManager::bpm_increase(Action * pAction, Hydrogen* pHydrogen, targeted_element ) {
pHydrogen->getAudioEngine()->lock( RIGHT_HERE );

Expand Down
5 changes: 5 additions & 0 deletions src/core/MidiAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ class MidiActionManager : public H2Core::Object
bool redo_action(Action * , H2Core::Hydrogen * , targeted_element );
bool gain_level_absolute(Action * , H2Core::Hydrogen * , targeted_element );
bool pitch_level_absolute(Action * , H2Core::Hydrogen * , targeted_element );
bool humanize_velocity_absolute(Action * , H2Core::Hydrogen * , targeted_element );
bool humanize_time_absolute(Action * , H2Core::Hydrogen * , targeted_element );
bool swing_absolute(Action * , H2Core::Hydrogen * , targeted_element );
bool fill_value_absolute(Action * , H2Core::Hydrogen * , targeted_element );
bool fill_randomize_absolute(Action * , H2Core::Hydrogen * , targeted_element );

QStringList eventList;

Expand Down
4 changes: 2 additions & 2 deletions src/core/Smf/Smf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,8 @@ void SMFWriter::save( const QString& sFilename, std::shared_ptr<Song> pSong )
FOREACH_NOTE_CST_IT_BOUND(notes,it,nNote) {
Note *pNote = it->second;
if ( pNote ) {
float rnd = (float)rand()/(float)RAND_MAX;
if ( pNote->get_probability() < rnd ) {
float fThreshold = pSong->getThreshold();
if ( pNote->get_probability() < fThreshold ) {
continue;
}

Expand Down
29 changes: 26 additions & 3 deletions src/gui/src/Mixer/MixerLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,16 +676,29 @@ MasterMixerLine::MasterMixerLine(QWidget* parent)
m_pPeakLCD->setPalette( lcdPalette );

m_pHumanizeVelocityRotary = new Rotary( this, Rotary::TYPE_NORMAL, tr( "Humanize velocity" ), false, true );
m_pHumanizeVelocityRotary->move( 74, 88 );
m_pHumanizeVelocityRotary->move( 74, 43 );
connect( m_pHumanizeVelocityRotary, SIGNAL( valueChanged(Rotary*) ), this, SLOT( rotaryChanged(Rotary*) ) );
m_pHumanizeVelocityRotary->setAction( new Action("HUMANIZE_VELOCITY_ABSOLUTE") );

m_pHumanizeTimeRotary = new Rotary( this, Rotary::TYPE_NORMAL, tr( "Humanize time" ), false, true );
m_pHumanizeTimeRotary->move( 74, 125 );
m_pHumanizeTimeRotary->move( 74, 80 );
connect( m_pHumanizeTimeRotary, SIGNAL( valueChanged(Rotary*) ), this, SLOT( rotaryChanged(Rotary*) ) );
m_pHumanizeTimeRotary->setAction( new Action("HUMANIZE_TIME_ABSOLUTE") );

m_pSwingRotary = new Rotary( this, Rotary::TYPE_NORMAL, tr( "16th-note Swing" ), false, true );
m_pSwingRotary->move( 74, 162 );
m_pSwingRotary->move( 74, 117 );
connect( m_pSwingRotary, SIGNAL( valueChanged(Rotary*) ), this, SLOT( rotaryChanged(Rotary*) ) );
m_pSwingRotary->setAction( new Action("SWING_ABSOLUTE") );

m_pFillValueRotary = new Rotary( this, Rotary::TYPE_NORMAL, tr( "Fill" ), false, false );
m_pFillValueRotary->move( 74, 172 );
connect( m_pFillValueRotary, SIGNAL( valueChanged(Rotary*) ), this, SLOT( rotaryChanged(Rotary*) ) );
m_pFillValueRotary->setAction( new Action("FILL_VALUE_ABSOLUTE") );

m_pFillRandomizeRotary = new Rotary( this, Rotary::TYPE_NORMAL, tr( "Randomize" ), false, false );
m_pFillRandomizeRotary->move( 74, 209 );
connect( m_pFillRandomizeRotary, SIGNAL( valueChanged(Rotary*) ), this, SLOT( rotaryChanged(Rotary*) ) );
m_pFillRandomizeRotary->setAction( new Action("FILL_RANDOMIZE_ABSOLUTE") );

// Mute btn
m_pMuteBtn = new ToggleButton(
Expand Down Expand Up @@ -816,6 +829,8 @@ void MasterMixerLine::updateMixerLine()
m_pHumanizeTimeRotary->setValue( pSong->getHumanizeTimeValue() );
m_pHumanizeVelocityRotary->setValue( pSong->getHumanizeVelocityValue() );
m_pSwingRotary->setValue( pSong->getSwingFactor() );
m_pFillValueRotary->setValue( pSong->getFillValue() );
m_pFillRandomizeRotary->setValue( pSong->getFillRandomize() );
m_pMuteBtn->setPressed( pSong->getIsMuted() );
}
else {
Expand Down Expand Up @@ -843,6 +858,14 @@ void MasterMixerLine::rotaryChanged( Rotary *pRef )
pHydrogen->getSong()->setSwingFactor( fVal );
sMsg = tr( "Set swing factor [%1]").arg( fVal, 0, 'f', 2 );
}
else if ( pRef == m_pFillValueRotary ) {
pHydrogen->getSong()->setFillValue( fVal );
sMsg = trUtf8( "Set fill value [%1]").arg( fVal, 0, 'f', 2 );
}
else if ( pRef == m_pFillRandomizeRotary ) {
pHydrogen->getSong()->setFillRandomize( fVal );
sMsg = trUtf8( "Set fill randomize [%1]").arg( fVal, 0, 'f', 2 );
}
else {
ERRORLOG( "[knobChanged] Unhandled knob" );
}
Expand Down
3 changes: 3 additions & 0 deletions src/gui/src/Mixer/MixerLine.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,9 @@ class MasterMixerLine: public PixmapWidget
Rotary * m_pHumanizeTimeRotary;
Rotary * m_pHumanizeVelocityRotary;

Rotary * m_pFillValueRotary;
Rotary * m_pFillRandomizeRotary;

ToggleButton * m_pMuteBtn;
};

Expand Down