1 /*
2  * Copyright 2017 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 OBOE_HELLO_OBOE_ENGINE_H
18 #define OBOE_HELLO_OBOE_ENGINE_H
19 
20 #include <oboe/Oboe.h>
21 
22 #include "SoundGenerator.h"
23 #include "LatencyTuningCallback.h"
24 #include "IRestartable.h"
25 #include "DefaultErrorCallback.h"
26 
27 constexpr int32_t kBufferSizeAutomatic = 0;
28 
29 class HelloOboeEngine : public IRestartable {
30 
31 public:
32     HelloOboeEngine();
33 
34     virtual ~HelloOboeEngine() = default;
35 
36     void tap(bool isDown);
37 
38     /**
39      * Open and start a stream.
40      * @return error or OK
41      */
42     oboe::Result start();
43 
44     /**
45      * Stop and close the stream.
46      */
47     void stop();
48 
49     // From IRestartable
50     void restart() override;
51 
52     // These methods reset the underlying stream with new properties
53 
54     /**
55      * Set the audio device which should be used for playback. Can be set to oboe::kUnspecified if
56      * you want to use the default playback device (which is usually the built-in speaker if
57      * no other audio devices, such as headphones, are attached).
58      *
59      * @param deviceId the audio device id, can be obtained through an {@link AudioDeviceInfo} object
60      * using Java/JNI.
61     */
62     void setDeviceId(int32_t deviceId);
63 
64     void setChannelCount(int channelCount);
65 
66     void setAudioApi(oboe::AudioApi audioApi);
67 
68     void setBufferSizeInBursts(int32_t numBursts);
69 
70     /**
71      * Calculate the current latency between writing a frame to the output stream and
72      * the same frame being presented to the audio hardware.
73      *
74      * Here's how the calculation works:
75      *
76      * 1) Get the time a particular frame was presented to the audio hardware
77      * @see AudioStream::getTimestamp
78      * 2) From this extrapolate the time which the *next* audio frame written to the stream
79      * will be presented
80      * 3) Assume that the next audio frame is written at the current time
81      * 4) currentLatency = nextFramePresentationTime - nextFrameWriteTime
82      *
83      * @return  Output Latency in Milliseconds
84      */
85     double getCurrentOutputLatencyMillis();
86 
87     bool isLatencyDetectionSupported();
88 
89 private:
90     oboe::Result reopenStream();
91     oboe::Result createPlaybackStream();
92 
93     std::shared_ptr<oboe::AudioStream> mStream;
94     std::unique_ptr<LatencyTuningCallback> mLatencyCallback;
95     std::unique_ptr<DefaultErrorCallback> mErrorCallback;
96     std::shared_ptr<SoundGenerator> mAudioSource;
97     bool mIsLatencyDetectionSupported = false;
98 
99     int32_t        mDeviceId = oboe::Unspecified;
100     int32_t        mChannelCount = oboe::Unspecified;
101     oboe::AudioApi mAudioApi = oboe::AudioApi::Unspecified;
102     std::mutex     mLock;
103 };
104 
105 #endif //OBOE_HELLO_OBOE_ENGINE_H
106