~ubuntu-branches/ubuntu/feisty/muse/feisty

« back to all changes in this revision

Viewing changes to synti/stklib/Clarinet.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2002-04-23 17:28:23 UTC
  • Revision ID: james.westby@ubuntu.com-20020423172823-w8yplzr81a759xa3
Tags: upstream-0.5.2
ImportĀ upstreamĀ versionĀ 0.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************/
 
2
/*  Waveguide Clarinet model ala Smith    */
 
3
/*  after McIntyre, Schumacher, Woodhouse */
 
4
/*  by Perry Cook, 1995-96                */
 
5
/*                                        */
 
6
/*  This is a waveguide model, and thus   */
 
7
/*  relates to various Stanford Univ.     */
 
8
/*  and possibly Yamaha and other patents.*/
 
9
/*                                        */
 
10
/*   Controls:    CONTROL1 = reedStiffns  */
 
11
/*                CONTROL2 = noiseGain    */
 
12
/*                CONTROL3 = vibFreq      */
 
13
/*                MOD_WHEEL= vibAmt       */
 
14
/******************************************/
 
15
 
 
16
#include "Clarinet.h"
 
17
#include "SKINI11.msg"
 
18
 
 
19
Clarinet :: Clarinet(MY_FLOAT lowestFreq)
 
20
{
 
21
  length = (long) (SRATE / lowestFreq + 1);
 
22
  delayLine = new DLineL(length);
 
23
  reedTable = new ReedTabl;
 
24
  reedTable->setOffset((MY_FLOAT) 0.7);
 
25
  reedTable->setSlope((MY_FLOAT) -0.3);
 
26
  filter = new OneZero;
 
27
  envelope = new Envelope;
 
28
  noise = new Noise;
 
29
 
 
30
  // Concatenate the STK RAWWAVE_PATH to the rawwave file
 
31
  char file[128];
 
32
  strcpy(file, RAWWAVE_PATH);
 
33
  vibr = new RawWvIn(strcat(file,"rawwaves/sinewave.raw"),"looping");
 
34
  vibr->setFreq((MY_FLOAT) 5.735);
 
35
  outputGain = (MY_FLOAT) 1.0;
 
36
  noiseGain = (MY_FLOAT) 0.2;
 
37
  vibrGain = (MY_FLOAT) 0.1;
 
38
}
 
39
 
 
40
Clarinet :: ~Clarinet()
 
41
{
 
42
  delete delayLine;
 
43
  delete reedTable;
 
44
  delete filter;
 
45
  delete envelope;
 
46
  delete noise;
 
47
  delete vibr;
 
48
}
 
49
 
 
50
void Clarinet :: clear()
 
51
{
 
52
  delayLine->clear();
 
53
  filter->tick((MY_FLOAT) 0.0);
 
54
}
 
55
 
 
56
void Clarinet :: setFreq(MY_FLOAT frequency)
 
57
{
 
58
  delayLine->setDelay         /* length - approx filter delay */
 
59
    ((SRATE / frequency) * (MY_FLOAT) 0.5 - (MY_FLOAT) 1.5);
 
60
}
 
61
 
 
62
void Clarinet :: startBlowing(MY_FLOAT amplitude,MY_FLOAT rate)
 
63
{
 
64
  envelope->setRate(rate);
 
65
  envelope->setTarget(amplitude); 
 
66
}
 
67
 
 
68
void Clarinet :: stopBlowing(MY_FLOAT rate)
 
69
{
 
70
  envelope->setRate(rate);
 
71
  envelope->setTarget((MY_FLOAT) 0.0); 
 
72
}
 
73
 
 
74
void Clarinet :: noteOn(MY_FLOAT freq, MY_FLOAT amp)
 
75
{
 
76
  this->setFreq(freq);
 
77
  this->startBlowing((MY_FLOAT) 0.55 + (amp * (MY_FLOAT) 0.30),amp * (MY_FLOAT) 0.005);
 
78
  outputGain = amp + (MY_FLOAT) 0.001;
 
79
#if defined(_debug_)        
 
80
  printf("Clarinet : NoteOn: Freq=%lf Amp=%lf\n",freq,amp);
 
81
#endif    
 
82
}
 
83
 
 
84
void Clarinet :: noteOff(MY_FLOAT amp)
 
85
{
 
86
  this->stopBlowing(amp * (MY_FLOAT) 0.01);
 
87
#if defined(_debug_)        
 
88
  printf("Clarinet : NoteOff: Amp=%lf\n",amp);
 
89
#endif    
 
90
}
 
91
 
 
92
MY_FLOAT Clarinet :: tick()
 
93
{
 
94
  MY_FLOAT pressureDiff;
 
95
  MY_FLOAT breathPressure;
 
96
    
 
97
  breathPressure = envelope->tick(); 
 
98
  breathPressure += breathPressure * 
 
99
    noiseGain * noise->tick();
 
100
  breathPressure += breathPressure *
 
101
    vibrGain * vibr->tick();
 
102
  pressureDiff = filter->tick(delayLine->lastOut());           /* differential pressure  */     
 
103
  pressureDiff = (pressureDiff * (MY_FLOAT) -0.95) - breathPressure; /* of reflected and mouth */
 
104
  lastOutput = delayLine->tick(breathPressure +                /* perform scattering     */
 
105
                               pressureDiff * reedTable->lookup(pressureDiff)); /* in economical way      */
 
106
  lastOutput *= outputGain;
 
107
  return lastOutput;
 
108
}
 
109
 
 
110
void Clarinet :: controlChange(int number, MY_FLOAT value)
 
111
{
 
112
#if defined(_debug_)        
 
113
  printf("Clarinet : ControlChange: Number=%i Value=%f\n",number,value);
 
114
#endif    
 
115
  if (number == __SK_ReedStiffness_)
 
116
    reedTable->setSlope((MY_FLOAT) -0.44 + ((MY_FLOAT) 0.26 * value * NORM_7));
 
117
  else if (number == __SK_NoiseLevel_)
 
118
    noiseGain = (value * NORM_7 * (MY_FLOAT) 0.4);
 
119
  else if (number == __SK_ModFrequency_)
 
120
    vibr->setFreq((value * NORM_7 * (MY_FLOAT) 12.0));
 
121
  else if (number == __SK_ModWheel_)
 
122
    vibrGain = (value * NORM_7 * (MY_FLOAT) 0.5);
 
123
  else if (number == __SK_AfterTouch_Cont_) {
 
124
    envelope->setValue(value * NORM_7);
 
125
  }
 
126
  else  {
 
127
    printf("Clarinet : Undefined Control Number!!\n");
 
128
  }
 
129
}