4 * Copyright (c) 2007 Scott Wilson <i@scottwilson.ca>. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Created by Scott Wilson on 22/06/2007.
21 * Modified by James Harkins on 28/07/2007.
26 #include "SC_PlugIn.h"
29 //////////////////////////////////////////////////////////////////////////////////////////////////
31 // Visual C++ doesn't have fpclassify (C99), so define it here if needed
34 enum { FP_NORMAL
, FP_NAN
, FP_INFINITE
, FP_SUBNORMAL
};
36 static int sc_fpclassify(float x
)
39 int kind
= _fpclass((double)x
);
55 result
= FP_SUBNORMAL
;
58 result
= FP_SUBNORMAL
;
67 inline int sc_fpclassify(float x
)
69 return std::fpclassify(x
);
73 //////////////////////////////////////////////////////////////////////////////////////////////////
75 static InterfaceTable
*ft
;
77 struct CheckBadValues
: public Unit
83 // declare unit generator functions
86 void CheckBadValues_Ctor(CheckBadValues
* unit
);
87 void CheckBadValues_next(CheckBadValues
* unit
, int inNumSamples
);
90 static const char *CheckBadValues_fpclassString(int fpclass
);
91 inline int CheckBadValues_fold_fpclasses(int fpclass
);
93 //////////////////////////////////////////////////////////////////////////////////////////////////
95 void CheckBadValues_Ctor(CheckBadValues
* unit
)
97 unit
->prevclass
= FP_NORMAL
;
99 SETCALC(CheckBadValues_next
);
100 CheckBadValues_next(unit
, 1);
104 void CheckBadValues_next(CheckBadValues
* unit
, int inNumSamples
)
107 float *out
= ZOUT(0);
109 int post
= (int) ZIN0(2);
115 case 1: // post a line on every bad value
118 classification
= sc_fpclassify(samp
);
119 switch (classification
)
122 printf("Infinite number found in Synth %d, ID: %d\n", unit
->mParent
->mNode
.mID
, (int)id
);
126 printf("NaN found in Synth %d, ID: %d\n", unit
->mParent
->mNode
.mID
, (int)id
);
130 printf("Denormal found in Synth %d, ID: %d\n", unit
->mParent
->mNode
.mID
, (int)id
);
141 classification
= CheckBadValues_fold_fpclasses(sc_fpclassify(samp
));
142 if(classification
!= unit
->prevclass
) {
143 if(unit
->sameCount
== 0) {
144 printf("CheckBadValues: %s found in Synth %d, ID %d\n",
145 CheckBadValues_fpclassString(classification
), unit
->mParent
->mNode
.mID
, (int)id
);
147 printf("CheckBadValues: %s found in Synth %d, ID %d (previous %d values were %s)\n",
148 CheckBadValues_fpclassString(classification
), unit
->mParent
->mNode
.mID
, (int)id
,
149 (int)unit
->sameCount
, CheckBadValues_fpclassString(unit
->prevclass
)
154 switch (classification
)
169 unit
->prevclass
= classification
;
175 classification
= sc_fpclassify(samp
);
176 switch (classification
)
195 const char *CheckBadValues_fpclassString(int fpclass
)
198 case FP_NORMAL
: return "normal";
199 case FP_NAN
: return "NaN";
200 case FP_INFINITE
: return "infinity";
202 case FP_ZERO
: return "zero";
204 case FP_SUBNORMAL
: return "denormal";
205 default: return "unknown";
210 inline int CheckBadValues_fold_fpclasses(int fpclass
)
213 case FP_ZERO
: return FP_NORMAL
; // a bit hacky. we mean "zero is fine too".
214 default: return fpclass
;
218 inline int CheckBadValues_fold_fpclasses(int fpclass
)
224 ////////////////////////////////////////////////////////////////////
226 // the load function is called by the host when the plug-in is loaded
231 DefineSimpleUnit(CheckBadValues
);