1
/********************************************/
2
/* MandPlyr Player Expert Object to control*/
3
/* commuted dual plucked-string model */
4
/* by Perry Cook, 1995-96 */
5
/********************************************/
12
#include "SKINI11.msg"
14
MandPlyr :: MandPlyr() : Instrmnt()
17
strings = new VoicMang(NUM_STRINGS,"Mandolin");
20
strumRate = (long) (SRATE * 0.1); // ( 1/(0.1) = 10Hz)
22
skill = (MY_FLOAT) 0.90;
23
for (i=0;i<NUM_STRINGS;i++) {
25
amps[i] = (MY_FLOAT) 0;
30
MandPlyr :: ~MandPlyr()
36
void MandPlyr :: noteOnN(short num, MY_FLOAT amp)
40
MY_FLOAT isErr,errDir;
43
errDir = noise->tick();
48
if (isErr < (0.4 * (1.0 - skill))) { /* Should we err here? */
52
strumCount = strumRate;
54
if (errDir < 0.0) error = -1; /* random error +/- 1/2 step */
60
while (notDone && i<NUM_STRINGS) {
64
tags[i] = strings->noteOnN((MY_FLOAT) num + error,amp);
67
printf("Must Reallocate a note\n");
74
temp = strings->oldestVoice();
76
while (notDone && i<NUM_STRINGS) {
81
tags[i] = strings->noteOnN((MY_FLOAT) num + error,amp);
87
if (notDone) printf("Can't allocate a new note\n");
90
void MandPlyr :: noteOffN(short num,MY_FLOAT amp)
94
temp = strings->noteOffN(num,amp);
95
if (temp>0) { // Usual Case
96
for (i=0;i<NUM_STRINGS;i++) {
97
if (tags[i] == temp) {
100
amps[i] = (MY_FLOAT) 0.0;
104
else { // In case note already off
105
for (i=0;i<NUM_STRINGS;i++) { // from strumming
106
if (nums[i] == num) { // Just clear its entry
107
strings->noteOffT(num,amp);
110
amps[i] = (MY_FLOAT) 0.0;
114
if (strumming == 2) strumming = 0;
117
MY_FLOAT MandPlyr :: tick()
123
if (strumCount <= 0) {
124
for (i=0;i<NUM_STRINGS;i++) {
126
strings->kill(tags[i]);
127
temp2 = (MY_FLOAT) fabs(noise->tick());
128
if (temp2 > 0.2 * (1.0 - skill))
129
tags[i] = strings->noteOnN(nums[i],amps[i]);
132
strumCount = strumRate;
133
strumCount = strumCount +
134
(long) (strumCount * (noise->tick() * (1.0 - skill)));
135
if (strumming == 2) strumming = 0;
138
for (i=0;i<NUM_STRINGS;i++) {
142
tags[i] = strings->noteOnN(nums[i],amps[i]);
146
lastOutput = strings->tick();
151
/* Some very basic Mandolin Chords */
152
/* Base Strings: G D A E */
153
/* G Chord: G D B G */
154
/* C Chord: G E C G */
155
/* D Chord: A D A F# */
156
/* E Chord: G# E B G# */
157
/* A Chord: A E C# A */
158
/* B Chord: B D# B F# */
162
void MandPlyr :: playChord(MY_FLOAT amp, char *chordString)
165
char chordStr[NUM_CHORDS+1] = {"GCDEAB"};
166
short chords[NUM_CHORDS][4] = {
173
short whichChord = -1;
176
if (tags[i] >= 0) strings->noteOffT(tags[i],amp);
178
for (i=0;i<NUM_CHORDS;i++) {
179
if (chordString[0]==chordStr[i])
183
if (chordString[0] == 0) {
186
if (whichChord == -1) {
187
printf("I don't know this chord: %s\n",chordString);
191
nums[i] = chords[whichChord][i];
192
tags[i] = -2 - (i * 10 * (200 - (int) amp));
199
void MandPlyr :: controlChange(int number, MY_FLOAT value)
202
printf("MandPlyr : ControlChange: Number=%i Value=%f\n",number,value);
205
if (number == __SK_BodySize_)
206
strings->controlChange(number,value);
207
else if (number == __SK_PickPosition_)
208
strings->controlChange(number,value);
209
else if (number == __SK_StringDamping_)
210
strings->controlChange(number,value);
211
else if (number == __SK_StringDetune_)
212
strings->controlChange(number,value);
214
else if (number == __SK_Strumming_) {
220
else if (number == __SK_NotStrumming_)
222
else if (number == __SK_PlayerSkill_)
223
skill = value * (MY_FLOAT) NORM_7;
224
else if (number == __SK_StrumSpeed_)
225
strumRate = (long) (SRATE * value * NORM_7); // (0 - 1Hz.)
227
printf("MandPlyr : Undefined Control Number!!\n");