New default argument to keyOn and keyOff in Envelope, fix in setTime function, updates to Guitar string coupling, EGuitar tcl interface, reordering of operations in Flute algorithm.

This commit is contained in:
Gary Scavone
2020-03-15 16:45:30 -04:00
parent 444dab21fd
commit a8b6affd8c
6 changed files with 67 additions and 29 deletions

View File

@@ -12,7 +12,8 @@ namespace stk {
This class implements a simple linear line envelope generator
which is capable of ramping to an arbitrary target value by a
specified \e rate. It also responds to simple \e keyOn and \e
keyOff messages, ramping to 1.0 on keyOn and to 0.0 on keyOff.
keyOff messages, ramping to a specified target (default = 1.0) on
keyOn and to a specified target (default = 0.0) on keyOff.
by Perry R. Cook and Gary P. Scavone, 1995--2019.
*/
@@ -31,11 +32,11 @@ class Envelope : public Generator
//! Assignment operator.
Envelope& operator= ( const Envelope& e );
//! Set target = 1.
void keyOn( void ) { this->setTarget( 1.0 ); };
//! Start ramping to specified target (default = 1).
void keyOn( StkFloat target = 1.0 ) { this->setTarget( target ); };
//! Set target = 0.
void keyOff( void ) { this->setTarget( 0.0 ); };
//! Start ramping to specified target (default = 0).
void keyOff( StkFloat target = 0.0 ) { this->setTarget( target ); };
//! Set the \e rate.
/*!
@@ -46,7 +47,7 @@ class Envelope : public Generator
//! Set the \e rate based on a positive time duration (seconds).
/*!
The \e rate is calculated such that the envelope will ramp from
a value of 0.0 to 1.0 in the specified time duration.
the current value to the current target in the specified time duration.
*/
void setTime( StkFloat time );

View File

@@ -123,11 +123,12 @@ inline StkFloat Flute :: tick( unsigned int )
breathPressure += breathPressure * ( noiseGain_ * noise_.tick() + vibratoGain_ * vibrato_.tick() );
StkFloat temp = -filter_.tick( boreDelay_.lastOut() );
temp = dcBlock_.tick( temp ); // Block DC on reflection.
//temp = dcBlock_.tick( temp ); // Block DC on reflection.
pressureDiff = breathPressure - (jetReflection_ * temp);
pressureDiff = jetDelay_.tick( pressureDiff );
pressureDiff = jetTable_.tick( pressureDiff ) + (endReflection_ * temp);
//pressureDiff = jetTable_.tick( pressureDiff ) + (endReflection_ * temp);
pressureDiff = dcBlock_.tick(jetTable_.tick( pressureDiff )) + (endReflection_ * temp); // moved the DC blocker to after the jet non-linearity (GPS, 29 Jan. 2020)
lastFrame_[0] = (StkFloat) 0.3 * boreDelay_.tick( pressureDiff );
lastFrame_[0] *= outputGain_;

View File

@@ -132,17 +132,20 @@ class Guitar : public Stk
StkFrames lastFrame_;
};
// NOTE: It is not possible to implement the Smith coupled string model here because the Twang class does
// not currently offer the chance to have access to a traveling-wave component. Thus, the coupling
// implemented here is approximate.
inline StkFloat Guitar :: tick( StkFloat input )
{
StkFloat temp, output = 0.0;
lastFrame_[0] /= strings_.size(); // evenly spread coupling across strings
lastFrame_[0] = couplingGain_ * couplingFilter_.tick( lastFrame_[0] ) / strings_.size();
for ( unsigned int i=0; i<strings_.size(); i++ ) {
if ( stringState_[i] ) {
temp = input;
// If pluckGain < 0.2, let string ring but don't pluck it.
if ( filePointer_[i] < excitation_.frames() && pluckGains_[i] > 0.2 )
temp += pluckGains_[i] * excitation_[filePointer_[i]++];
temp += couplingGain_ * couplingFilter_.tick( lastFrame_[0] ); // bridge coupling
temp += lastFrame_[0]; // bridge coupling
output += strings_[i].tick( temp );
// Check if string energy has decayed sufficiently to turn it off.
if ( stringState_[i] == 1 ) {

View File

@@ -100,7 +100,7 @@ scale .left.bPressure -from 0 -to 128 -length 200 \
-tickinterval 32 -showvalue true -bg grey66
scale .left.pitch -from 0 -to 128 -length 200 \
-command {changePitch } -variable pitch \
-command {changePitch } -variable pitch -resolution 0.1 \
-orient horizontal -label "MIDI Note Number" \
-tickinterval 32 -showvalue true -bg grey66

View File

@@ -19,6 +19,12 @@ array set stringNote {
5 59
6 64
}
array set powerNote {
1 40
2 47
3 52
4 59
}
#array set stringAmp { 1 64 2 64 3 64 4 64 5 64 6 64 }
array set stringAmp {
1 64
@@ -53,10 +59,12 @@ pack .message -padx 5 -pady 10
# Configure "note on" buttons
frame .top
button .top.on -text Strum -bg grey66 -command strum
button .top.off -text "All Off" -bg grey66 -command allOff
button .top.exit -text "Quit" -bg grey66 -command quit
button .top.on -text Strum -padx 5 -bg grey66 -command strum
button .top.power -text "Power Chord" -padx 5 -bg grey66 -command powerchord
button .top.off -text "All Off" -padx 5 -bg grey66 -command allOff
button .top.exit -text "Quit" -padx 5 -bg grey66 -command quit
pack .top.on -side left -padx 5
pack .top.power -side left -padx 5 -padx 5
pack .top.off -side left -padx 5 -pady 10
pack .top.exit -side left -padx 5 -pady 10
pack .top
@@ -117,13 +125,26 @@ proc quit {} {
}
proc strum {} {
global stringNote stringAmp
global stringAmp stringNote
for {set n 1} {$n < 7} {incr n} {
puts [format "NoteOn %2.3f %d %3.2f %3.2f" [expr rand()*0.04] $n $stringNote($n) $stringAmp($n)]
}
flush stdout
}
proc powerchord {} {
global stringNote powerNote stringAmp cont28 cont72
set cont72 80
set cont28 90
puts [format "ControlChange 0.0 0 72 %3.2f" $cont72]
puts [format "ControlChange 0.0 0 28 %3.2f" $cont28]
for {set n 1} {$n < 5} {incr n} {
set stringNote($n) $powerNote($n)
puts [format "NoteOn %2.3f %d %3.2f %3.2f" [expr rand()*0.01] $n $powerNote($n) $stringAmp($n)]
}
flush stdout
}
proc allOff {} {
global stringNote stringAmp
for {set n 1} {$n < 7} {incr n} {
@@ -167,32 +188,32 @@ proc setStringAmp {value} {
frame .strings -bg grey88 -borderwidth 5 -relief groove
scale .strings.s1 -from $stringMin(1) -to [expr $stringMin(1)+$stringRange] \
-length 350 -orient horizontal -label "String 1: Note Number" \
-tickinterval 5 -showvalue true -variable $stringNote(1) \
-tickinterval 5 -showvalue true -variable stringNote(1) \
-command {setNote 1}
scale .strings.s2 -from $stringMin(2) -to [expr $stringMin(2)+$stringRange] \
-length 350 -orient horizontal -label "String 2: Note Number" \
-tickinterval 5 -showvalue true -variable $stringNote(2) \
-tickinterval 5 -showvalue true -variable stringNote(2) \
-command {setNote 2}
scale .strings.s3 -from $stringMin(3) -to [expr $stringMin(3)+$stringRange] \
-length 350 -orient horizontal -label "String 3: Note Number" \
-tickinterval 5 -showvalue true -variable $stringNote(3) \
-tickinterval 5 -showvalue true -variable stringNote(3) \
-command {setNote 3}
scale .strings.s4 -from $stringMin(4) -to [expr $stringMin(4)+$stringRange] \
-length 350 -orient horizontal -label "String 4: Note Number" \
-tickinterval 5 -showvalue true -variable $stringNote(4) \
-tickinterval 5 -showvalue true -variable stringNote(4) \
-command {setNote 4}
scale .strings.s5 -from $stringMin(5) -to [expr $stringMin(5)+$stringRange] \
-length 350 -orient horizontal -label "String 5: Note Number" \
-tickinterval 5 -showvalue true -variable $stringNote(5) \
-tickinterval 5 -showvalue true -variable stringNote(5) \
-command {setNote 5}
scale .strings.s6 -from $stringMin(6) -to [expr $stringMin(6)+$stringRange] \
-length 350 -orient horizontal -label "String 6: Note Number" \
-tickinterval 5 -showvalue true -variable $stringNote(6) \
-tickinterval 5 -showvalue true -variable stringNote(6) \
-command {setNote 6}
button .strings.b1 -text Pluck -command { pluckOne 1 }
@@ -202,7 +223,6 @@ button .strings.b4 -text Pluck -command { pluckOne 4 }
button .strings.b5 -text Pluck -command { pluckOne 5 }
button .strings.b6 -text Pluck -command { pluckOne 6 }
grid .strings -column 0 -row 0
grid .strings.b1 -column 1 -row 0 -padx 5 -pady 5
grid .strings.b2 -column 1 -row 1
grid .strings.b3 -column 1 -row 2
@@ -218,9 +238,20 @@ grid .strings.s5 -column 0 -row 4 -padx 5 -pady 5
grid .strings.s6 -column 0 -row 5 -padx 5 -pady 5
set stringSelect "All"
ttk::combobox .strings.combo \
-values [ list "All" "String 1" "String 2" "String 3" "String 4" "String 5" "String 6" ] \
-width 8 -textvariable stringSelect -justify center
set values [ list "All" "String 1" "String 2" "String 3" "String 4" "String 5" "String 6" ]
ttk::combobox .strings.combo -values $values \
-width 10 -state readonly -textvariable stringSelect -justify center
bind .strings.combo <<ComboboxSelected>> {
global stringAmp velocity
switch [%W get] {
"String 1" { set velocity $stringAmp(1) }
"String 2" { set velocity $stringAmp(2) }
"String 3" { set velocity $stringAmp(3) }
"String 4" { set velocity $stringAmp(4) }
"String 5" { set velocity $stringAmp(5) }
"String 6" { set velocity $stringAmp(6) }
}
}
scale .strings.velocity -from 0 -to 128 -length 350 \
-orient horizontal -label "Note Velocity" \
@@ -229,7 +260,7 @@ scale .strings.velocity -from 0 -to 128 -length 350 \
grid .strings.combo -column 1 -row 7
grid .strings.velocity -column 0 -row 7 -padx 5 -pady 10
pack .strings
pack .strings -side right
set cbpath .strings.combo
@@ -261,4 +292,4 @@ proc center_the_toplevel { w } {
}
return
}
}

View File

@@ -5,7 +5,8 @@
This class implements a simple linear line envelope generator
which is capable of ramping to an arbitrary target value by a
specified \e rate. It also responds to simple \e keyOn and \e
keyOff messages, ramping to 1.0 on keyOn and to 0.0 on keyOff.
keyOff messages, ramping to a specified target (default = 1.0) on
keyOn and to a specified target (default = 0.0) on keyOff.
by Perry R. Cook and Gary P. Scavone, 1995--2019.
*/
@@ -64,7 +65,8 @@ void Envelope :: setTime( StkFloat time )
handleError( StkError::WARNING ); return;
}
rate_ = 1.0 / ( time * Stk::sampleRate() );
//rate_ = 1.0 / ( time * Stk::sampleRate() );
rate_ = fabs(target_ - value_) / ( time * Stk::sampleRate() );
}
void Envelope :: setTarget( StkFloat target )