├── .gitignore ├── LICENSE.md ├── README.md ├── build.gradle ├── settings.gradle └── src └── main └── java └── uk └── ac └── ox └── eng └── stepcounter ├── DataPoint.java ├── DetectionStage.java ├── FilterStage.java ├── PostProcessStage.java ├── PreProcessStage.java ├── ScoringStage.java └── StepCounter.java /.gitignore: -------------------------------------------------------------------------------- 1 | # gradle stuff 2 | /.gradle/ 3 | /gradle/ 4 | .gradle 5 | gradle-app.setting 6 | gradlew* 7 | 8 | # builds 9 | /bin/ 10 | /build/ 11 | 12 | # Eclipse stuff 13 | /.settings/ 14 | .project 15 | .classpath 16 | 17 | # Android studio stuff 18 | .idea/ 19 | local.properties -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ## License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Step counter algorithm, Java version 2 | ==================================== 3 | 4 | This is a step counter algorithm based on the Windowed Peak Detection method. 5 | The algorithm is implemented in Java and makes no assumption about the operating system it runs on. 6 | 7 | ## Compile 8 | 9 | This code is provided as a gradle project. To compile it, import it in Eclipse or use 10 | 11 | gradle fatJar 12 | 13 | the compiled jar file will be placed in ./build/libs 14 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | version = '1.0' 4 | sourceCompatibility = 1.7 5 | targetCompatibility = 1.7 6 | 7 | repositories { 8 | jcenter() 9 | mavenCentral() 10 | } 11 | 12 | // create just the jar file 13 | jar { 14 | manifest { 15 | attributes 'Implementation-Title': 'Oxford Step Counter', 16 | 'Implementation-Version': version 17 | } 18 | } 19 | 20 | // create a single Jar with all dependencies 21 | task fatJar(type: Jar) { 22 | manifest { 23 | attributes 'Implementation-Title': 'Oxford Step Counter', 24 | 'Implementation-Version': version 25 | } 26 | baseName = project.name + '-all' 27 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 28 | with jar 29 | } 30 | 31 | 32 | // In this section you declare the dependencies for your production and test code 33 | dependencies { 34 | testCompile 'junit:junit:4.12' 35 | } 36 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'StepCounterJava' 2 | -------------------------------------------------------------------------------- /src/main/java/uk/ac/ox/eng/stepcounter/DataPoint.java: -------------------------------------------------------------------------------- 1 | package uk.ac.ox.eng.stepcounter; 2 | 3 | /** 4 | * Created by Jamie Brynes on 1/22/2017. 5 | */ 6 | 7 | public class DataPoint { 8 | 9 | private float time; 10 | private float magnitude; 11 | 12 | 13 | // Toggle for special End-Of-Stream flag. 14 | private boolean eos; 15 | 16 | public DataPoint(long time, float magnitude) { 17 | this.time = (float) time; 18 | this.magnitude = magnitude; 19 | eos = false; 20 | } 21 | 22 | public DataPoint(float time, float magnitude) { 23 | this.time = time; 24 | this.magnitude = magnitude; 25 | } 26 | 27 | public void setEos(boolean val) { 28 | eos = val; 29 | } 30 | 31 | public boolean getEos() { 32 | return eos; 33 | } 34 | 35 | public float getMagnitude() { 36 | return magnitude; 37 | } 38 | 39 | public void setMagnitude(float magnitude) { 40 | this.magnitude = magnitude; 41 | } 42 | 43 | public float getTime() { 44 | return time; 45 | } 46 | 47 | public void setTime(float time) { 48 | this.time = time; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/uk/ac/ox/eng/stepcounter/DetectionStage.java: -------------------------------------------------------------------------------- 1 | package uk.ac.ox.eng.stepcounter; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by Jamie Brynes on 1/22/2017. 7 | */ 8 | 9 | public class DetectionStage implements Runnable { 10 | 11 | private List inputQueue; 12 | private List outputQueue; 13 | private DataPoint dp; 14 | 15 | private boolean active; 16 | 17 | private int count; 18 | private float mean; 19 | private float std; 20 | 21 | /* 22 | Section for defining parameters. 23 | */ 24 | private final float threshold = 1.2f; 25 | 26 | public DetectionStage(List input, List output) { 27 | 28 | inputQueue = input; 29 | outputQueue = output; 30 | active = false; 31 | count = 0; 32 | mean = 0f; 33 | std = 0f; 34 | dp = null; 35 | } 36 | 37 | public void run() { 38 | 39 | active = true; 40 | 41 | while (active) { 42 | 43 | if (!inputQueue.isEmpty()) { 44 | dp = inputQueue.remove(0); 45 | } 46 | 47 | if (dp != null) { 48 | 49 | // Special handing for end of stream. 50 | if (dp.getEos()) { 51 | active = false; 52 | outputQueue.add(dp); 53 | continue; 54 | } 55 | 56 | // Update calculations of std and mean. 57 | count++; 58 | float o_mean = mean; 59 | switch(count) { 60 | case 1: 61 | mean = dp.getMagnitude(); 62 | std = 0f; 63 | break; 64 | case 2: 65 | mean = (mean + dp.getMagnitude()) / 2; 66 | std = (float)Math.sqrt(Math.pow(dp.getMagnitude() - mean,2) + Math.pow(o_mean - mean,2)) / 2; 67 | break; 68 | default: 69 | mean = (dp.getMagnitude() + (count - 1) * mean) / count; 70 | std = (float)Math.sqrt(((count - 2) * Math.pow(std,2) / (count - 1)) + Math.pow(o_mean - mean, 2) + Math.pow(dp.getMagnitude() - mean,2) / count); 71 | } 72 | 73 | // Once we have enough data points to have a reasonable mean/standard deviation, start detecting 74 | if (count > 15) { 75 | if ((dp.getMagnitude() - mean) > std * threshold) { 76 | // This is a peak 77 | outputQueue.add(new DataPoint(dp.getTime(),dp.getMagnitude())); 78 | } 79 | } 80 | 81 | dp = null; 82 | } 83 | } 84 | 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/uk/ac/ox/eng/stepcounter/FilterStage.java: -------------------------------------------------------------------------------- 1 | package uk.ac.ox.eng.stepcounter; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by Jamie Brynes on 1/22/2017. 8 | */ 9 | 10 | public class FilterStage implements Runnable { 11 | 12 | private List inputQueue; 13 | private List outputQueue; 14 | 15 | private ArrayList window; 16 | private ArrayList filterCoefficients; 17 | 18 | private final static int FILTER_LENGTH = 13; 19 | private final static float FILTER_STD = 0.35f; 20 | private float filter_sum = 0.0f; 21 | 22 | private boolean active = false; 23 | private DataPoint dp; 24 | 25 | public FilterStage(List input, List output) { 26 | 27 | inputQueue = input; 28 | outputQueue = output; 29 | 30 | window = new ArrayList(); 31 | filterCoefficients = FilterStage.generateCoefficients(); 32 | for (int i = 0; i < FILTER_LENGTH; i++) 33 | { 34 | filter_sum += filterCoefficients.get(i); 35 | } 36 | 37 | dp = null; 38 | } 39 | 40 | public void run() { 41 | 42 | active = true; 43 | 44 | while (active) { 45 | 46 | if (!inputQueue.isEmpty()) { 47 | dp = inputQueue.remove(0); 48 | } 49 | 50 | if (dp != null) { 51 | 52 | 53 | // Special handling for final data point. 54 | if (dp.getEos()) { 55 | active = false; 56 | outputQueue.add(dp); 57 | continue; 58 | } 59 | 60 | window.add(dp); 61 | 62 | if (window.size() == FILTER_LENGTH) { 63 | 64 | float sum = 0; 65 | for (int i = 0; i < FILTER_LENGTH; i++) { 66 | sum += window.get(i).getMagnitude() * filterCoefficients.get(i); 67 | } 68 | 69 | DataPoint new_dp = new DataPoint(window.get(FILTER_LENGTH / 2).getTime(), sum / filter_sum); 70 | outputQueue.add(new_dp); 71 | window.remove(0); 72 | } 73 | 74 | dp = null; 75 | } 76 | } 77 | 78 | } 79 | 80 | private static ArrayList generateCoefficients() { 81 | 82 | // Create a window of the correct size. 83 | ArrayList coeff = new ArrayList(); 84 | 85 | for (int i = 0; i < FILTER_LENGTH; i++) { 86 | float value = (float) Math.pow(Math.E, -0.5 * Math.pow((i - (FILTER_LENGTH - 1) / 2) / (FILTER_STD * (FILTER_LENGTH - 1) / 2), 2)); 87 | coeff.add(value); 88 | } 89 | 90 | return coeff; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/uk/ac/ox/eng/stepcounter/PostProcessStage.java: -------------------------------------------------------------------------------- 1 | package uk.ac.ox.eng.stepcounter; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by Jamie Brynes on 1/22/2017. 8 | */ 9 | 10 | public class PostProcessStage implements Runnable { 11 | 12 | private List inputQueue; 13 | private OnNewStepDetected newStepInterface; 14 | private OnEndOfData endOfDataInterface; 15 | 16 | private DataPoint current; 17 | private DataPoint dp; 18 | private boolean active; 19 | 20 | 21 | /* 22 | Section for parameter definitions 23 | */ 24 | 25 | private final int timeThreshold = 200; 26 | 27 | 28 | 29 | public interface OnNewStepDetected { 30 | 31 | void incrementSteps(); 32 | } 33 | 34 | public interface OnEndOfData { 35 | void EodCallback(); 36 | } 37 | 38 | public PostProcessStage(List input, OnNewStepDetected newStepCallback, OnEndOfData endOfDataCallback) { 39 | 40 | inputQueue = input; 41 | newStepInterface = newStepCallback; 42 | endOfDataInterface = endOfDataCallback; 43 | 44 | active = false; 45 | current = null; 46 | dp = null; 47 | } 48 | 49 | public void run() { 50 | 51 | active = true; 52 | 53 | while (active) { 54 | 55 | if (!inputQueue.isEmpty()) { 56 | dp = inputQueue.remove(0); 57 | } 58 | 59 | if (dp != null) { 60 | 61 | if (dp.getEos()) { 62 | active = false; 63 | endOfDataInterface.EodCallback(); 64 | continue; 65 | } 66 | 67 | // First point handler. 68 | if (current == null) { 69 | current = dp; 70 | } 71 | else { 72 | 73 | // If the time difference exceeds the threshold, we have a confirmed step 74 | if ((dp.getTime() - current.getTime()) > timeThreshold) { 75 | current = dp; 76 | newStepInterface.incrementSteps(); 77 | } else { 78 | // Keep the point with the largest magnitude. 79 | if (dp.getMagnitude() > current.getMagnitude()) { 80 | current = dp; 81 | } 82 | } 83 | 84 | } 85 | 86 | dp = null; 87 | } 88 | 89 | 90 | } 91 | 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/uk/ac/ox/eng/stepcounter/PreProcessStage.java: -------------------------------------------------------------------------------- 1 | package uk.ac.ox.eng.stepcounter; 2 | 3 | 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | /** 8 | * Created by Jamie Brynes on 1/22/2017. 9 | */ 10 | 11 | public class PreProcessStage implements Runnable { 12 | 13 | private List inputQueue; 14 | private List outputQueue; 15 | 16 | private ArrayList window; 17 | private DataPoint dp; 18 | 19 | private final int interpolationTime = 10; // In ms. 20 | private final float timeScalingFactor = 1000000f; // Convert ns to ms. 21 | private int interpolationCount = 0; 22 | 23 | private float startTime = -1; 24 | 25 | private boolean active = false; 26 | 27 | public PreProcessStage(List input, List output) { 28 | 29 | inputQueue = input; 30 | outputQueue = output; 31 | window = new ArrayList<>(); 32 | dp = null; 33 | } 34 | 35 | public void run() { 36 | 37 | active = true; 38 | 39 | while (active) { 40 | 41 | // If there is a new point, retrieve it, limit operations on inputQueue to not block other threads. 42 | if (!inputQueue.isEmpty()) { 43 | dp = inputQueue.remove(0); 44 | } 45 | 46 | //Scale time and add to window. 47 | if (dp != null) { 48 | 49 | // This signals the end of the data stream. 50 | if (dp.getEos()) { 51 | active = false; 52 | outputQueue.add(dp); 53 | continue; 54 | } 55 | 56 | // Handling for the first data point in the stream. 57 | if (startTime == -1) { 58 | startTime = dp.getTime(); 59 | } 60 | 61 | dp.setTime(scaleTime(dp.getTime())); 62 | window.add(dp); 63 | dp = null; 64 | } 65 | 66 | // We have enough data points to interpolate. 67 | if (window.size() >= 2) { 68 | float time1 = window.get(0).getTime(); 69 | float time2 = window.get(1).getTime(); 70 | 71 | // This defines the number of points that could exist in between the points. 72 | int numberOfPoints = (int) Math.ceil((time2 - time1) / interpolationTime); 73 | 74 | for (int i = 0; i < numberOfPoints; i++) { 75 | float interpTime = (float) interpolationCount * interpolationTime; 76 | 77 | // Check if the next interpolated time is between these two points. 78 | if (time1 <= interpTime && interpTime < time2) { 79 | DataPoint interpolated = linearInterpolate(window.get(0), window.get(1), interpTime); 80 | outputQueue.add(interpolated); 81 | interpolationCount += 1; 82 | } 83 | } 84 | 85 | // Remove the oldest element in the list. 86 | window.remove(0); 87 | } 88 | } 89 | 90 | } 91 | 92 | private float scaleTime(float ogTime) { 93 | 94 | return (ogTime - startTime) / timeScalingFactor; 95 | } 96 | 97 | private DataPoint linearInterpolate(DataPoint dp1, DataPoint dp2, float interpTime) { 98 | 99 | float dt = dp2.getTime() - dp1.getTime(); 100 | float dv = dp2.getMagnitude() - dp1.getMagnitude(); 101 | float mag = (dv/dt) * (interpTime - dp1.getTime()) + dp1.getMagnitude(); 102 | 103 | return new DataPoint(interpTime,mag); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/uk/ac/ox/eng/stepcounter/ScoringStage.java: -------------------------------------------------------------------------------- 1 | package uk.ac.ox.eng.stepcounter; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by Jamie Brynes on 1/22/2017. 8 | */ 9 | 10 | public class ScoringStage implements Runnable { 11 | 12 | private List inputQueue; 13 | private List outputQueue; 14 | 15 | private ArrayList window; 16 | 17 | private boolean active; 18 | private DataPoint dp; 19 | 20 | 21 | /* 22 | Section for parameter definitions 23 | */ 24 | private static final int WINDOW_SIZE = 35; 25 | 26 | public ScoringStage(List input, List output) { 27 | 28 | inputQueue = input; 29 | outputQueue = output; 30 | 31 | window = new ArrayList<>(); 32 | active = false; 33 | dp = null; 34 | 35 | } 36 | 37 | public void run() { 38 | 39 | active = true; 40 | 41 | while (active) { 42 | 43 | if (!inputQueue.isEmpty()) { 44 | dp = inputQueue.remove(0); 45 | } 46 | 47 | if (dp != null) { 48 | 49 | // Special handling for final data point. 50 | if (dp.getEos()) { 51 | active = false; 52 | outputQueue.add(dp); 53 | continue; 54 | } 55 | 56 | window.add(dp); 57 | 58 | if (window.size() == WINDOW_SIZE) { 59 | 60 | // Calculate score and append to the output window. 61 | float score = scorePeak(window); 62 | outputQueue.add(new DataPoint(window.get(WINDOW_SIZE / 2).getTime(),score)); 63 | // Pop out the oldest point. 64 | window.remove(0); 65 | } 66 | dp = null; 67 | } 68 | 69 | } 70 | 71 | } 72 | 73 | private float scorePeak(ArrayList data) { 74 | int midpoint = (int) data.size() / 2; 75 | float diffLeft = 0f; 76 | float diffRight = 0f; 77 | 78 | for(int i = 0; i < midpoint; i++) { 79 | diffLeft += data.get(midpoint).getMagnitude() - data.get(i).getMagnitude(); 80 | } 81 | 82 | for (int j = midpoint + 1; j < data.size(); j++) { 83 | diffRight += data.get(midpoint).getMagnitude() - data.get(j).getMagnitude(); 84 | } 85 | 86 | return (diffRight + diffLeft) / (WINDOW_SIZE - 1); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/uk/ac/ox/eng/stepcounter/StepCounter.java: -------------------------------------------------------------------------------- 1 | package uk.ac.ox.eng.stepcounter; 2 | 3 | import java.util.ArrayList; 4 | import java.lang.Math; 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | /** 9 | * Created by Jamie Brynes on 1/22/2017. 10 | */ 11 | public class StepCounter { 12 | 13 | 14 | /** 15 | * This is the interface for getting updates when we get a step occuring. Simple listener/broadcaster pattern. 16 | */ 17 | public interface OnStepUpdateListener { 18 | 19 | /** 20 | * This method will be called by a background thread and hence any UI changes done in the implementation of this MUST be done in the runInUiThread() way. 21 | */ 22 | void onStepUpdate(int steps); 23 | 24 | } 25 | 26 | public interface OnFinishedProcessingListener { 27 | 28 | /** 29 | * This method will get called when the remaining data points finish processing. The owner of the object can make UI adjustments as necessary. 30 | */ 31 | void onFinishedProcessing(); 32 | 33 | } 34 | 35 | private float samplingFreq; 36 | private int steps; 37 | private boolean active; 38 | 39 | private List rawData; 40 | private List ppData; 41 | private List smoothData; 42 | private List peakScoreData; 43 | private List peakData; 44 | 45 | private Runnable preProcessStage; 46 | private Runnable filterStage; 47 | private Runnable scoringStage; 48 | private Runnable detectionStage; 49 | private Runnable postProcessStage; 50 | 51 | private ArrayList callbacks; 52 | private PostProcessStage.OnNewStepDetected newStepCallback; 53 | private PostProcessStage.OnEndOfData eodCallback; 54 | private OnFinishedProcessingListener finishCallback; 55 | 56 | 57 | /** 58 | * [Constructor for the StepCounter module.] 59 | * @param samplingFreq [This parameter describes the sampling frequency of the sensor.] 60 | * @return [Instance of Step Counter] 61 | */ 62 | public StepCounter(float samplingFreq) { 63 | 64 | this.samplingFreq = samplingFreq; 65 | newStepCallback = new PostProcessStage.OnNewStepDetected() { 66 | @Override 67 | public void incrementSteps() { 68 | incSteps(); 69 | } 70 | }; 71 | 72 | eodCallback = new PostProcessStage.OnEndOfData() { 73 | @Override 74 | public void EodCallback() { 75 | if (finishCallback != null) { 76 | finishCallback.onFinishedProcessing(); 77 | } 78 | } 79 | }; 80 | 81 | // Initialize callback list. 82 | callbacks = new ArrayList<>(); 83 | 84 | } 85 | 86 | /** 87 | * This function describes the set-up required for a new data recording. 88 | */ 89 | private void setUp() { 90 | this.steps = 0; 91 | this.active = false; 92 | 93 | // Initialize thread-safe lists. 94 | rawData = Collections.synchronizedList(new ArrayList()); 95 | ppData = Collections.synchronizedList(new ArrayList()); 96 | smoothData = Collections.synchronizedList(new ArrayList()); 97 | peakScoreData = Collections.synchronizedList(new ArrayList()); 98 | peakData = Collections.synchronizedList(new ArrayList()); 99 | 100 | } 101 | 102 | /** 103 | * [This function starts the Step Counter algorithm.] 104 | */ 105 | public void start(){ 106 | 107 | if (!active) { 108 | // Reset threads and stages. 109 | setUp(); 110 | active = true; 111 | new Thread( new PreProcessStage(rawData, ppData)).start(); 112 | new Thread( new FilterStage(ppData, smoothData)).start(); 113 | new Thread( new ScoringStage(smoothData, peakScoreData)).start(); 114 | new Thread( new DetectionStage(peakScoreData, peakData)).start(); 115 | new Thread( new PostProcessStage(peakData, newStepCallback, eodCallback)).start(); 116 | } 117 | } 118 | 119 | 120 | /** 121 | * [This function stops the Step Counter algorithm. Current behavior is to finish processing all remaining samples before ending the threads.] 122 | */ 123 | public void stop() { 124 | 125 | if (active) { 126 | //Signal that this is the end of the data stream. This is a special data point that says 'end of stream.' 127 | active = false; 128 | DataPoint dp = new DataPoint(0f,0f); 129 | dp.setEos(true); 130 | rawData.add(dp); 131 | } 132 | 133 | } 134 | 135 | 136 | /** 137 | * [This function allows the user to add a callback for when we get a new step!]] 138 | * @param listener [Implementation of the OnStepUpdateListener] 139 | */ 140 | public synchronized void addOnStepUpdateListener(OnStepUpdateListener listener) { 141 | callbacks.add(listener); 142 | } 143 | 144 | 145 | public synchronized void setOnFinishedProcessingListener(OnFinishedProcessingListener listener){ 146 | finishCallback = listener; 147 | } 148 | 149 | 150 | /** 151 | * [This function allows for callbacks to listeners when steps is updated.] 152 | */ 153 | public synchronized void incSteps() { 154 | steps++; 155 | for (OnStepUpdateListener listener : callbacks) { 156 | listener.onStepUpdate(steps); 157 | } 158 | } 159 | 160 | 161 | /** 162 | * [This function is the public interface to add a new accelerometer sample to the step counter algorithm.] 163 | * @param time [The timestamp of the sample in nanoseconds.] 164 | * @param sample [An array of accelerometer values [x,y,z] in m/s^2.] 165 | */ 166 | public void processSample(long time, float[] sample) { 167 | 168 | if (active) { 169 | float magnitude = 0; 170 | for (float m : sample) { 171 | magnitude += m * m; 172 | } 173 | magnitude = (float) Math.sqrt(magnitude); 174 | 175 | rawData.add(new DataPoint(time, magnitude)); 176 | } 177 | } 178 | 179 | 180 | /** 181 | * [Getter function for the number steps.] 182 | * @return [Returns the number of steps.] 183 | */ 184 | public synchronized int getSteps() { 185 | return this.steps; 186 | } 187 | 188 | 189 | /** 190 | * [Getter function for the sampling frequency.] 191 | * @return [Returns the sampling frequency.] 192 | */ 193 | public float getSamplingFreq() { 194 | return samplingFreq; 195 | } 196 | 197 | 198 | /** 199 | * [Setter function for the sampling frequency.] 200 | * @param samplingFreq [The sampling frequency to set.] 201 | */ 202 | public void setSamplingFreq(float samplingFreq) { 203 | this.samplingFreq = samplingFreq; 204 | } 205 | 206 | } 207 | --------------------------------------------------------------------------------