28#include <wx/textfile.h>
108 auto samplesleft = len - WindowSizeInt;
109 auto lastsubthresholdsample = start;
120 for(
auto i = start; samplesleft >= 10;
121 i += (WindowSizeInt - 1) , samplesleft -= (WindowSizeInt - 1)) {
132 lastsubthresholdsample = i;
142 if(samplesleft > 10) {
147 size_t remaining = 2*WindowSizeInt+1;
151 Floats buffer{ remaining };
153 lastsubthresholdsample, remaining);
159 int atrend =
sgn(buffer[1]-buffer[0]);
160 int ztrend =
sgn(buffer[WindowSizeInt+1]-buffer[WindowSizeInt]);
169 erg =
TestEnergy(t, lastsubthresholdsample, WindowSizeInt);
179 wxASSERT(WindowSizeInt < SignalWindowSizeInt);
181 for(i = 0; i + WindowSizeInt < SignalWindowSizeInt; i++) {
184 int testThreshold = 0;
194 TestSignChangesUpdate(sc,WindowSizeInt,buffer[i],buffer[i+1],buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
201 TestSignChangesUpdate(sc,WindowSizeInt,buffer[i],buffer[i+1],buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
208 TestDirectionChangesUpdate(dc,WindowSizeInt,atrend,buffer[i],buffer[i+1],ztrend,buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
215 TestDirectionChangesUpdate(dc,WindowSizeInt,atrend,buffer[i],buffer[i+1],ztrend,buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
222 if(tests >= testThreshold)
229 return i + lastsubthresholdsample;
256 auto samplesleft = len - WindowSizeInt;
257 auto lastsubthresholdsample =
end;
267 for(
auto i =
end - WindowSizeInt; samplesleft >= 10;
268 i -= (WindowSizeInt - 1) , samplesleft -= (WindowSizeInt - 1)) {
283 lastsubthresholdsample = i+WindowSizeInt;
293 if(samplesleft > 10) {
297 size_t remaining = 2*WindowSizeInt+1;
301 Floats buffer{ remaining };
303 lastsubthresholdsample - remaining, remaining);
307 int atrend =
sgn(buffer[remaining - 2]-buffer[remaining - 1]);
309 int ztrend =
sgn(buffer[remaining - WindowSizeInt - 2] -
310 buffer[remaining - WindowSizeInt
324 erg =
TestEnergy(t, lastsubthresholdsample, WindowSizeInt);
332 for(i = remaining - 1; i > WindowSizeInt; i--) {
334 int testThreshold = 0;
344 TestSignChangesUpdate(sc,WindowSizeInt,buffer[i],buffer[i+1],buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
350 TestSignChangesUpdate(sc,WindowSizeInt,buffer[i],buffer[i+1],buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
356 TestDirectionChangesUpdate(dc,WindowSizeInt,atrend,buffer[i],buffer[i+1],ztrend,buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
362 TestDirectionChangesUpdate(dc,WindowSizeInt,atrend,buffer[i],buffer[i+1],ztrend,buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
367 if(tests >= testThreshold)
374 return lastsubthresholdsample - remaining + i;
399 unsigned int WindowSizeInt = (
unsigned int)(rate *
mWindowSize);
403 auto lastsubthresholdsample = start;
412 for(
auto i = start; samplesleft >= 10;
413 i += (WindowSizeInt - 1) , samplesleft -= (WindowSizeInt - 1)) {
425 lastsubthresholdsample = i;
435 if(samplesleft > 10) {
440 size_t remaining = 2*WindowSizeInt+1;
444 Floats buffer{ remaining };
446 lastsubthresholdsample, remaining);
450 int atrend =
sgn(buffer[1]-buffer[0]);
451 int ztrend =
sgn(buffer[WindowSizeInt+1]-buffer[WindowSizeInt]);
460 erg =
TestEnergy(t, lastsubthresholdsample, WindowSizeInt);
468 for(i = 0; i < SilentWindowSizeInt - WindowSizeInt; i++) {
470 int testThreshold = 0;
480 TestSignChangesUpdate(sc,WindowSizeInt,buffer[i],buffer[i+1],buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
486 TestSignChangesUpdate(sc,WindowSizeInt,buffer[i],buffer[i+1],buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
492 TestDirectionChangesUpdate(dc,WindowSizeInt,atrend,buffer[i],buffer[i+1],ztrend,buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
498 TestDirectionChangesUpdate(dc,WindowSizeInt,atrend,buffer[i],buffer[i+1],ztrend,buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
503 if(tests < testThreshold)
510 return i + lastsubthresholdsample;
535 unsigned int WindowSizeInt = (
unsigned int)(rate *
mWindowSize);
538 auto samplesleft = len - WindowSizeInt;
539 auto lastsubthresholdsample =
end;
548 for(
auto i =
end - WindowSizeInt; samplesleft >= 10;
549 i -= (WindowSizeInt - 1), samplesleft -= (WindowSizeInt -1 )) {
562 lastsubthresholdsample = i+WindowSizeInt;
573 if(samplesleft > 10) {
577 const size_t remaining = 2*WindowSizeInt+1;
581 Floats buffer{ remaining };
583 lastsubthresholdsample - remaining, remaining);
587 int atrend =
sgn(buffer[remaining - 2] - buffer[remaining - 1]);
589 sgn(buffer[remaining - WindowSizeInt - 2] -
590 buffer[remaining - WindowSizeInt - 2]);
597 erg =
TestEnergy(t, lastsubthresholdsample, WindowSizeInt);
605 for(i = remaining - 1; i > WindowSizeInt; i--) {
608 int testThreshold = 0;
618 TestSignChangesUpdate(sc,WindowSizeInt,buffer[i],buffer[i+1],buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
624 TestSignChangesUpdate(sc,WindowSizeInt,buffer[i],buffer[i+1],buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
630 TestDirectionChangesUpdate(dc,WindowSizeInt,atrend,buffer[i],buffer[i+1],ztrend,buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
636 TestDirectionChangesUpdate(dc,WindowSizeInt,atrend,buffer[i],buffer[i+1],ztrend,buffer[i+WindowSizeInt],buffer[i+WindowSizeInt+1]);
643 if(tests < testThreshold)
650 return lastsubthresholdsample - remaining + i;
723 return (tests >= testThreshold);
752 double sumerg, sumerg2;
753 double sumsc, sumsc2;
754 double sumdc, sumdc2;
759 unsigned int WindowSizeInt = (
unsigned int)(rate *
mWindowSize);
786 auto samplesleft = len - WindowSizeInt;
789 for(
auto i = start; samplesleft >= 10;
790 i += (WindowSizeInt - 1), samplesleft -= (WindowSizeInt -1) ) {
799 sumerg +=(double)erg;
800 sumerg2 += pow((
double)erg,2);
804 sumsc2 += pow((
double)sc,2);
809 sumdc2 += pow((
double)dc,2);
821 auto text =
XO(
"Calibration Results\n");
824 XO(
"Energy -- mean: %1.4f sd: (%1.4f)\n")
827 XO(
"Sign Changes -- mean: %1.4f sd: (%1.4f)\n")
830 XO(
"Direction Changes -- mean: %1.4f sd: (%1.4f)\n")
835 XO(
"Calibration Complete"),
836 wxOK | wxICON_INFORMATION,
846 bool dcLow,
bool dcHigh)
863 auto originalLen = len;
866 Floats buffer{ blockSize };
876 for(
decltype(block) i = 0; i< block; i++)
878 sum += buffer[i]*buffer[i];
893 prevErg = prevErg + (double)(fabs(add) - fabs(drop))/len;
904 auto originalLen = len;
907 unsigned long signchanges = 1;
910 Floats buffer{ blockSize };
918 if (len == originalLen)
921 currentsign =
sgn(buffer[0]);
926 for(
decltype(block) i = 0; i< block; i++)
928 if(
sgn(buffer[i]) != currentsign)
930 currentsign =
sgn(buffer[i]);
938 return (
double)signchanges / originalLen.
as_double();
948 if(
sgn(a1)!=
sgn(a2)) currentsignchanges -= 1.0/len;
949 if(
sgn(z1)!=
sgn(z2)) currentsignchanges += 1.0/len;
960 auto originalLen = len;
963 unsigned long directionchanges = 1;
964 float lastval=float(0);
967 Floats buffer{ blockSize };
975 if (len == originalLen) {
983 for(
decltype(block) i = 0; i< block; i++){
985 if(
sgn(buffer[i]-lastval) != lastdirection) {
987 lastdirection =
sgn(buffer[i] - lastval);
995 return (
double)directionchanges/originalLen.
as_double();
1004 int & atrend,
const float & a1,
const float & a2,
1005 int & ztrend,
const float & z1,
const float & z2)
1008 if(
sgn(a2 - a1)!= atrend ) {
1010 currentdirectionchanges -= 1.0/len;
1011 atrend =
sgn(a2-a1);
1013 if(
sgn(z2 - z1)!= ztrend){
1015 currentdirectionchanges += 1.0/len;
1016 ztrend =
sgn(z2-z1);
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Wrap wxMessageDialog so that caption IS translatable.
bool GetFloats(float *buffer, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
Retrieve samples from a track in floating-point format, regardless of the storage format.
double mThresholdAdjustment
void TestDirectionChangesUpdate(double ¤tdirectionchanges, int length, int &atrend, const float &a1, const float &a2, int &ztrend, const float &z1, const float &z2)
sampleCount OnBackward(const WaveTrack &t, sampleCount start, sampleCount len)
double TestDirectionChanges(const WaveTrack &t, sampleCount start, sampleCount len)
double mThresholdDirectionChangesUpper
void AdjustThreshold(double t)
double mThresholdDirectionChangesLower
double TestEnergy(const WaveTrack &t, sampleCount start, sampleCount len)
bool mUseDirectionChangesLow
sampleCount OffForward(const WaveTrack &t, sampleCount start, sampleCount len)
void TestEnergyUpdate(double &prevErg, int length, const float &drop, const float &add)
bool AboveThreshold(const WaveTrack &t, sampleCount start, sampleCount len)
double mThresholdSignChangesLower
bool mUseDirectionChangesHigh
double TestSignChanges(const WaveTrack &t, sampleCount start, sampleCount len)
void CalibrateNoise(const WaveTrack &t, sampleCount start, sampleCount len)
void SetKeyType(bool erg, bool scLow, bool scHigh, bool dcLow, bool dcHigh)
void TestSignChangesUpdate(double ¤tsignchanges, int length, const float &a1, const float &a2, const float &z1, const float &z2)
sampleCount OffBackward(const WaveTrack &t, sampleCount start, sampleCount len)
double mThresholdSignChangesUpper
sampleCount OnForward(const WaveTrack &t, sampleCount start, sampleCount len)
double mDirectionChangesSD
double mDirectionChangesMean
A Track that contains audio waveform data.
size_t GetMaxBlockSize() const override
This returns a nonnegative number of samples meant to size a memory buffer.
size_t GetBestBlockSize(sampleCount t) const override
This returns a nonnegative number of samples meant to size a memory buffer.
double GetRate() const override
Positions or offsets within audio files need a wide type.
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for, if Traits<Type>::iterated_type is defined.