real AudioExtractor::GetMaxAmplitude(real startTime, real duration) const { if (fSamples == NULL || duration < 0.0f) return 0.0f; uint32 i, start, end; real sample, max = -PG_HUGE; start = TimeToSample(startTime, true); end = TimeToSample(startTime + duration, true); if (end == start) return 0.0f; for (i = start; i < end; i++) { sample = PG_FABS(fSamples[i]); if (sample > 1.001f) continue; max = PG_MAX(max, sample); } return max; }
real AudioExtractor::GetRMSAmplitude(real startTime, real duration) const { if (fSamples == NULL || duration < 0.0f) return 0.0f; uint32 i, start, end; real sample, total = 0.0f; start = TimeToSample(startTime, true); end = TimeToSample(startTime + duration, true); if (end == start) return 0.0f; for (i = start; i < end; i++) { sample = PG_FABS(fSamples[i]); if (sample > 1.001f) continue; total += sample * sample; } total = total / (real)(end - start); return (real)sqrt(total); }
int DexApparatus::CheckAccelerationPeaks( float min_amplitude, float max_amplitude, int max_bad_peaks, const char *msg, const char *picture ) { const char *fmt; bool error = false; int bad_peaks = 0, lows = 0, highs = 0; int movements = 0; int first, last; int start_sample, end_sample, smpl; int i, j, n; double average, delta, peak; // First we should look for the start and end of the actual movement based on // events such as when the subject reaches the first target. FindAnalysisFrameRange( first, last ); // Step through each marked movement trigger. FindAnalysisEventRange( first, last ); for ( i = first; i < last - 1; i++ ) { if ( eventList[i].event == TRIGGER_MOVE_UP || eventList[i].event == TRIGGER_MOVE_DOWN ) { movements++; // Find when the next movement started. for ( j = i + 1; j < last - 1; j++ ) { if ( eventList[i].event == TRIGGER_MOVE_UP || eventList[i].event == TRIGGER_MOVE_DOWN ) break; } // Compute the average force through the movement. start_sample = TimeToSample( eventList[i].time ); end_sample = TimeToSample( eventList[j].time ); average = 0.0; n = 0; for ( smpl = start_sample; smpl < end_sample; smpl++ ) { average += acquiredHighAcceleration[smpl]; n++; } average /= n; // Find the peak force relative to the average during the period. peak = 0.0; for ( smpl = start_sample; smpl < end_sample; smpl++ ) { delta = fabs( acquiredHighAcceleration[smpl] - average ); if ( delta > peak ) peak = delta; } if ( peak < min_amplitude || peak > max_amplitude ) bad_peaks++; if ( peak < min_amplitude ) lows++; if ( peak > max_amplitude ) highs++; } } // Check if the computed number of incorrect starting positions is in the desired range. error = ( bad_peaks > max_bad_peaks ); // This format string is used to add debugging information to the event notification. // It is used whether there is an error or not. fmt = "%s\n\n Min Acc Peak: %.2f\n Max Acc Peak: %.2f\n\nTotal Movements: %d\n Errors Detected: %d\n Highs: %d\n Lows: %d\n Maximum Allowed: %d"; // If not, signal the error to the subject. // Here I take the approach of calling a method to signal the error. // We agree instead that the routine should either return a null pointer // if there is no error, or return the error message as a static string. if ( error ) { // If the user provided a message to signal a visibilty error, use it. // If not, generate a generic message. if ( !msg ) msg = "To many collisions outside acceleration range."; int response = fSignalError( MB_ABORTRETRYIGNORE, picture, fmt, msg, min_amplitude, max_amplitude, movements, bad_peaks, highs, lows, max_bad_peaks ); if ( response == IDABORT ) return( ABORT_EXIT ); if ( response == IDRETRY ) return( RETRY_EXIT ); if ( response == IDIGNORE ) return( IGNORE_EXIT ); } // This is my means of signalling the event to ground. monitor->SendEvent( fmt, "Peak Accelerations OK.", movements, bad_peaks, highs, lows, max_bad_peaks ); return( NORMAL_EXIT ); }