1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_AAUDIO_ISOCHRONOUS_CLOCK_MODEL_H
18 #define ANDROID_AAUDIO_ISOCHRONOUS_CLOCK_MODEL_H
19 
20 #include <stdint.h>
21 
22 namespace aaudio {
23 
24 /**
25  * Model an isochronous data stream using occasional timestamps as input.
26  * This can be used to predict the position of the stream at a given time.
27  *
28  * This class is not thread safe and should only be called from one thread.
29  */
30 class IsochronousClockModel {
31 
32 public:
33     IsochronousClockModel();
34     virtual ~IsochronousClockModel();
35 
36     void start(int64_t nanoTime);
37     void stop(int64_t nanoTime);
38 
39     void processTimestamp(int64_t framePosition, int64_t nanoTime);
40 
41     /**
42      * @param sampleRate rate of the stream in frames per second
43      */
44     void setSampleRate(int32_t sampleRate);
45 
getSampleRate()46     int32_t getSampleRate() const {
47         return mSampleRate;
48     }
49 
50     /**
51      * This must be set accurately in order to track the isochronous stream.
52      *
53      * @param framesPerBurst number of frames that stream advance at one time.
54      */
55     void setFramesPerBurst(int32_t framesPerBurst);
56 
getFramesPerBurst()57     int32_t getFramesPerBurst() const {
58         return mFramesPerBurst;
59     }
60 
61     /**
62      * Calculate an estimated time when the stream will be at that position.
63      *
64      * @param framePosition position of the stream in frames
65      * @return time in nanoseconds
66      */
67     int64_t convertPositionToTime(int64_t framePosition) const;
68 
69     /**
70      * Calculate an estimated position where the stream will be at the specified time.
71      *
72      * @param nanoTime time of interest
73      * @return position in frames
74      */
75     int64_t convertTimeToPosition(int64_t nanoTime) const;
76 
77     /**
78      * @param framesDelta difference in frames
79      * @return duration in nanoseconds
80      */
81     int64_t convertDeltaPositionToTime(int64_t framesDelta) const;
82 
83     /**
84      * @param nanosDelta duration in nanoseconds
85      * @return frames that stream will advance in that time
86      */
87     int64_t convertDeltaTimeToPosition(int64_t nanosDelta) const;
88 
89 private:
90     enum clock_model_state_t {
91         STATE_STOPPED,
92         STATE_STARTING,
93         STATE_SYNCING,
94         STATE_RUNNING
95     };
96 
97     int64_t             mMarkerFramePosition;
98     int64_t             mMarkerNanoTime;
99     int32_t             mSampleRate;
100     int32_t             mFramesPerBurst;
101     int32_t             mMaxLatenessInNanos;
102     clock_model_state_t mState;
103 
104     void update();
105 };
106 
107 } /* namespace aaudio */
108 
109 #endif //ANDROID_AAUDIO_ISOCHRONOUS_CLOCK_MODEL_H
110