blob: 32fef1b4a80a2982242850472e8ef588012724d6 [file] [log] [blame]
Phil Burkab177962016-11-18 17:11:59 -08001/*
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/**
18 * This is the 'C' ABI for Oboe.
19 */
20#ifndef OBOE_OBOEAUDIO_H
21#define OBOE_OBOEAUDIO_H
22
23#include "OboeDefinitions.h"
24
25typedef int32_t OboeDeviceId;
26typedef oboe_handle_t OboeStream;
27typedef oboe_handle_t OboeStreamBuilder;
28typedef oboe_handle_t OboeThread;
29
30#define OBOE_STREAM_NONE ((OboeStream)OBOE_HANDLE_INVALID)
31#define OBOE_STREAM_BUILDER_NONE ((OboeStreamBuilder)OBOE_HANDLE_INVALID)
32
33
34// ============================================================
35// Audio System
36// ============================================================
37
38/**
39 * @return time in the same clock domain as the timestamps
40 */
41oboe_nanoseconds_t Oboe_getNanoseconds(oboe_clockid_t clockid);
42
43/**
44 * The text is the ASCII symbol corresponding to the returnCode,
45 * or an English message saying the returnCode is unrecognized.
46 * This is intended for developers to use when debugging.
47 * It is not for display to users.
48 *
49 * @return pointer to a text representation of an Oboe result code.
50 */
51const char * Oboe_convertResultToText(oboe_result_t returnCode);
52
53/**
Phil Burk5a7bdb22016-11-22 15:52:04 -080054 * The text is the ASCII symbol corresponding to the stream state,
Phil Burkab177962016-11-18 17:11:59 -080055 * or an English message saying the state is unrecognized.
56 * This is intended for developers to use when debugging.
57 * It is not for display to users.
58 *
59 * @return pointer to a text representation of an Oboe state.
60 */
Phil Burk5a7bdb22016-11-22 15:52:04 -080061const char * Oboe_convertStreamStateToText(oboe_stream_state_t state);
Phil Burkab177962016-11-18 17:11:59 -080062
63// ============================================================
64// StreamBuilder
65// ============================================================
Phil Burk5a7bdb22016-11-22 15:52:04 -080066
Phil Burkab177962016-11-18 17:11:59 -080067/**
68 * Create a StreamBuilder that can be used to open a Stream.
69 *
Phil Burk5a7bdb22016-11-22 15:52:04 -080070 * The deviceId is initially unspecified, meaning that the current default device will be used.
71 *
72 * The default direction is OBOE_DIRECTION_OUTPUT.
73 * The default sharing mode is OBOE_SHARING_MODE_LEGACY.
74 * The data format, samplesPerFrames and sampleRate are unspecified and will be
75 * chosen by the device when it is opened.
76 *
Phil Burkab177962016-11-18 17:11:59 -080077 * OboeStreamBuilder_delete() must be called when you are done using the builder.
78 */
79oboe_result_t Oboe_createStreamBuilder(OboeStreamBuilder *builder);
80
81/**
82 * Request an audio device identified device using an ID.
83 * The ID is platform specific.
84 * On Android, for example, the ID could be obtained from the Java AudioManager.
85 *
Phil Burk5a7bdb22016-11-22 15:52:04 -080086 * By default, the primary device will be used.
Phil Burkab177962016-11-18 17:11:59 -080087 *
88 * @return OBOE_OK or a negative error.
89 */
90oboe_result_t OboeStreamBuilder_setDeviceId(OboeStreamBuilder builder, OboeDeviceId deviceId);
91
92/**
93 * Request a sample rate in Hz.
94 * The stream may be opened with a different sample rate.
95 * So the application should query for the actual rate after the stream is opened.
96 *
97 * Technically, this should be called the "frame rate" or "frames per second",
98 * because it refers to the number of complete frames transferred per second.
99 * But it is traditionally called "sample rate". Se we use that term.
100 *
101 * Default is OBOE_UNSPECIFIED.
102 *
103 * @return OBOE_OK or a negative error.
104 */
105oboe_result_t OboeStreamBuilder_setSampleRate(OboeStreamBuilder builder,
106 oboe_sample_rate_t sampleRate);
107
108/**
109 * Returns sample rate in Hertz (samples per second).
Phil Burk5a7bdb22016-11-22 15:52:04 -0800110 * @return OBOE_OK or a negative error.
Phil Burkab177962016-11-18 17:11:59 -0800111 */
112oboe_result_t OboeStreamBuilder_getSampleRate(OboeStreamBuilder builder,
113 oboe_sample_rate_t *sampleRate);
114
115
116/**
117 * Request a number of samples per frame.
118 * The stream may be opened with a different value.
119 * So the application should query for the actual value after the stream is opened.
120 *
121 * Default is OBOE_UNSPECIFIED.
122 *
123 * Note, this quantity is sometimes referred to as "channel count".
124 *
125 * @return OBOE_OK or a negative error.
126 */
127oboe_result_t OboeStreamBuilder_setSamplesPerFrame(OboeStreamBuilder builder,
128 int32_t samplesPerFrame);
129
130/**
131 * Note, this quantity is sometimes referred to as "channel count".
132 *
133 * @param builder handle provided by Oboe_createStreamBuilder()
134 * @param samplesPerFrame pointer to a variable to be set to samplesPerFrame.
135 * @return OBOE_OK or a negative error.
136 */
137oboe_result_t OboeStreamBuilder_getSamplesPerFrame(OboeStreamBuilder builder,
138 int32_t *samplesPerFrame);
139
140
141/**
142 * Request a sample data format, for example OBOE_AUDIO_FORMAT_PCM16.
143 * The application should query for the actual format after the stream is opened.
144 *
145 * @return OBOE_OK or a negative error.
146 */
147oboe_result_t OboeStreamBuilder_setFormat(OboeStreamBuilder builder, oboe_audio_format_t format);
148
149/**
Phil Burk5a7bdb22016-11-22 15:52:04 -0800150 * @return OBOE_OK or a negative error.
Phil Burkab177962016-11-18 17:11:59 -0800151 */
152oboe_result_t OboeStreamBuilder_getFormat(OboeStreamBuilder builder, oboe_audio_format_t *format);
153
154/**
155 * Request a mode for sharing the device.
156 * The requested sharing mode may not be available.
157 * So the application should query for the actual mode after the stream is opened.
158 *
159 * @param builder handle provided by Oboe_createStreamBuilder()
160 * @param sharingMode OBOE_SHARING_MODE_LEGACY or OBOE_SHARING_MODE_EXCLUSIVE
161 * @return OBOE_OK or a negative error.
162 */
163oboe_result_t OboeStreamBuilder_setSharingMode(OboeStreamBuilder builder,
164 oboe_sharing_mode_t sharingMode);
165
166/**
167 * Return requested sharing mode.
168 * @return OBOE_OK or a negative error
169 */
170oboe_result_t OboeStreamBuilder_getSharingMode(OboeStreamBuilder builder,
171 oboe_sharing_mode_t *sharingMode);
172
173/**
174 * Request the direction for a stream. The default is OBOE_DIRECTION_OUTPUT.
175 *
176 * @param builder handle provided by Oboe_createStreamBuilder()
177 * @param direction OBOE_DIRECTION_OUTPUT or OBOE_DIRECTION_INPUT
178 * @return OBOE_OK or a negative error.
179 */
180oboe_result_t OboeStreamBuilder_setDirection(OboeStreamBuilder builder,
181 oboe_direction_t direction);
182
183/**
184 * @param builder handle provided by Oboe_createStreamBuilder()
185 * @param direction pointer to a variable to be set to the currently requested direction.
186 * @return OBOE_OK or a negative error.
187 */
188oboe_result_t OboeStreamBuilder_getDirection(OboeStreamBuilder builder,
189 oboe_direction_t *direction);
190
191/**
192 * Open a stream based on the options in the StreamBuilder.
193 *
194 * OboeStream_close must be called when finished with the stream to recover
195 * the memory and to free the associated resources.
196 *
Phil Burk5a7bdb22016-11-22 15:52:04 -0800197 * @param builder handle provided by Oboe_createStreamBuilder()
198 * @param stream pointer to a variable to receive the new stream handle
199 * @return OBOE_OK or a negative error.
Phil Burkab177962016-11-18 17:11:59 -0800200 */
201oboe_result_t OboeStreamBuilder_openStream(OboeStreamBuilder builder, OboeStream *stream);
202
203/**
204 * Delete the resources associated with the StreamBuilder.
Phil Burk5a7bdb22016-11-22 15:52:04 -0800205 *
Phil Burkab177962016-11-18 17:11:59 -0800206 * @param builder handle provided by Oboe_createStreamBuilder()
207 * @return OBOE_OK or a negative error.
208 */
209oboe_result_t OboeStreamBuilder_delete(OboeStreamBuilder builder);
210
211// ============================================================
212// Stream Control
213// ============================================================
214
215/**
216 * Free the resources associated with a stream created by OboeStreamBuilder_openStream()
Phil Burk5a7bdb22016-11-22 15:52:04 -0800217 *
218 * @param stream handle provided by OboeStreamBuilder_openStream()
219 * @return OBOE_OK or a negative error.
Phil Burkab177962016-11-18 17:11:59 -0800220 */
221oboe_result_t OboeStream_close(OboeStream stream);
222
223/**
224 * Asynchronously request to start playing the stream. For output streams, one should
225 * write to the stream to fill the buffer before starting.
226 * Otherwise it will underflow.
Phil Burk5a7bdb22016-11-22 15:52:04 -0800227 * After this call the state will be in OBOE_STREAM_STATE_STARTING or OBOE_STREAM_STATE_STARTED.
228 *
229 * @param stream handle provided by OboeStreamBuilder_openStream()
230 * @return OBOE_OK or a negative error.
Phil Burkab177962016-11-18 17:11:59 -0800231 */
232oboe_result_t OboeStream_requestStart(OboeStream stream);
233
234/**
235 * Asynchronous request for the stream to pause.
236 * Pausing a stream will freeze the data flow but not flush any buffers.
237 * Use OboeStream_Start() to resume playback after a pause.
Phil Burk5a7bdb22016-11-22 15:52:04 -0800238 * After this call the state will be in OBOE_STREAM_STATE_PAUSING or OBOE_STREAM_STATE_PAUSED.
239 *
240 * @param stream handle provided by OboeStreamBuilder_openStream()
241 * @return OBOE_OK or a negative error.
Phil Burkab177962016-11-18 17:11:59 -0800242 */
243oboe_result_t OboeStream_requestPause(OboeStream stream);
244
245/**
246 * Asynchronous request for the stream to flush.
247 * Flushing will discard any pending data.
248 * This call only works if the stream is pausing or paused. TODO review
249 * Frame counters are not reset by a flush. They may be advanced.
Phil Burk5a7bdb22016-11-22 15:52:04 -0800250 * After this call the state will be in OBOE_STREAM_STATE_FLUSHING or OBOE_STREAM_STATE_FLUSHED.
251 *
252 * @param stream handle provided by OboeStreamBuilder_openStream()
253 * @return OBOE_OK or a negative error.
Phil Burkab177962016-11-18 17:11:59 -0800254 */
255oboe_result_t OboeStream_requestFlush(OboeStream stream);
256
257/**
258 * Asynchronous request for the stream to stop.
259 * The stream will stop after all of the data currently buffered has been played.
Phil Burk5a7bdb22016-11-22 15:52:04 -0800260 * After this call the state will be in OBOE_STREAM_STATE_STOPPING or OBOE_STREAM_STATE_STOPPED.
261 *
262 * @param stream handle provided by OboeStreamBuilder_openStream()
263 * @return OBOE_OK or a negative error.
Phil Burkab177962016-11-18 17:11:59 -0800264 */
265oboe_result_t OboeStream_requestStop(OboeStream stream);
266
267/**
Phil Burk5a7bdb22016-11-22 15:52:04 -0800268 * Query the current state, eg. OBOE_STREAM_STATE_PAUSING
Phil Burkab177962016-11-18 17:11:59 -0800269 *
Phil Burk5a7bdb22016-11-22 15:52:04 -0800270 * @param stream handle provided by OboeStreamBuilder_openStream()
271 * @param state pointer to a variable that will be set to the current state
Phil Burkab177962016-11-18 17:11:59 -0800272 * @return OBOE_OK or a negative error.
273 */
Phil Burk5a7bdb22016-11-22 15:52:04 -0800274oboe_result_t OboeStream_getState(OboeStream stream, oboe_stream_state_t *state);
Phil Burkab177962016-11-18 17:11:59 -0800275
276/**
277 * Wait until the current state no longer matches the input state.
278 *
279 * <pre><code>
Phil Burk5a7bdb22016-11-22 15:52:04 -0800280 * oboe_stream_state_t currentState;
281 * oboe_result_t result = OboeStream_getState(stream, &currentState);
282 * while (result == OBOE_OK && currentState != OBOE_STREAM_STATE_PAUSING) {
283 * result = OboeStream_waitForStateChange(
284 * stream, currentState, &currentState, MY_TIMEOUT_NANOS);
Phil Burkab177962016-11-18 17:11:59 -0800285 * }
286 * </code></pre>
287 *
288 * @param stream A handle provided by OboeStreamBuilder_openStream()
289 * @param inputState The state we want to avoid.
290 * @param nextState Pointer to a variable that will be set to the new state.
291 * @param timeoutNanoseconds Maximum number of nanoseconds to wait for completion.
Phil Burk5a7bdb22016-11-22 15:52:04 -0800292 * @return OBOE_OK or a negative error.
Phil Burkab177962016-11-18 17:11:59 -0800293 */
294oboe_result_t OboeStream_waitForStateChange(OboeStream stream,
Phil Burk5a7bdb22016-11-22 15:52:04 -0800295 oboe_stream_state_t inputState,
296 oboe_stream_state_t *nextState,
Phil Burkab177962016-11-18 17:11:59 -0800297 oboe_nanoseconds_t timeoutNanoseconds);
298
299// ============================================================
300// Stream I/O
301// ============================================================
302
303/**
304 * Read data from the stream.
305 *
306 * The call will wait until the read is complete or until it runs out of time.
307 * If timeoutNanos is zero then this call will not wait.
308 *
309 * Note that timeoutNanoseconds is a relative duration in wall clock time.
310 * Time will not stop if the thread is asleep.
311 * So it will be implemented using CLOCK_BOOTTIME.
312 *
313 * This call is "strong non-blocking" unless it has to wait for data.
314 *
315 * @param stream A stream created using OboeStreamBuilder_openStream().
316 * @param buffer The address of the first sample.
317 * @param numFrames Number of frames to read. Only complete frames will be written.
318 * @param timeoutNanoseconds Maximum number of nanoseconds to wait for completion.
319 * @return The number of frames actually written or a negative error.
320 */
321oboe_result_t OboeStream_read(OboeStream stream,
322 void *buffer,
323 int32_t numFrames,
324 oboe_nanoseconds_t timeoutNanoseconds);
325
326/**
327 * Write data to the stream.
328 *
329 * The call will wait until the write is complete or until it runs out of time.
330 * If timeoutNanos is zero then this call will not wait.
331 *
332 * Note that timeoutNanoseconds is a relative duration in wall clock time.
333 * Time will not stop if the thread is asleep.
334 * So it will be implemented using CLOCK_BOOTTIME.
335 *
336 * This call is "strong non-blocking" unless it has to wait for room in the buffer.
337 *
338 * @param stream A stream created using OboeStreamBuilder_openStream().
339 * @param buffer The address of the first sample.
340 * @param numFrames Number of frames to write. Only complete frames will be written.
341 * @param timeoutNanoseconds Maximum number of nanoseconds to wait for completion.
342 * @return The number of frames actually written or a negative error.
343 */
344oboe_result_t OboeStream_write(OboeStream stream,
345 const void *buffer,
346 int32_t numFrames,
347 oboe_nanoseconds_t timeoutNanoseconds);
348
349
350// ============================================================
351// High priority audio threads
352// ============================================================
353
354/**
355 * Create a thread with special properties for low latency audio performance.
356 * This thread can be used to implement a callback API.
357 *
358 * Note that this API is in flux.
359 *
360 * @param threadHandlePtr a pointer to receive a thread handle
361 * @param periodNanoseconds the estimated period at which the audio thread will need to wake up
362 * @param start_routine your thread entry point
363 * @param arg an argument that will be passed to your thread entry point
364 * @return OBOE_OK or a negative error.
365 */
366oboe_result_t Oboe_createAudioThread(OboeThread *threadHandlePtr,
367 oboe_nanoseconds_t periodNanoseconds,
368 void *(*start_routine)(void *), void *arg);
369
370/**
371 * Wait until the thread exits or an error occurs.
372 * The thread handle will be deleted.
373 *
374 * @param thread the thread handle passed back from Oboe_createAudioThread()
375 * @param returnArg a pointer to a variable to receive the return value
376 * @param timeoutNanoseconds Maximum number of nanoseconds to wait for completion.
377 * @return OBOE_OK or a negative error.
378 */
379oboe_result_t Oboe_joinAudioThread(OboeThread thread,
380 void **returnArg,
381 oboe_nanoseconds_t timeoutNanoseconds);
382
383// ============================================================
384// Stream - queries
385// ============================================================
386
387
388/**
389 * This can be used to adjust the latency of the buffer by changing
390 * the threshold where blocking will occur.
391 * By combining this with OboeStream_getUnderrunCount(), the latency can be tuned
392 * at run-time for each device.
393 *
394 * This cannot be set higher than OboeStream_getBufferCapacity().
395 *
396 * @param stream handle provided by OboeStreamBuilder_openStream()
397 * @param frames requested number of frames that can be filled without blocking
398 * @return actual number of frames or a negative error
399 */
400oboe_result_t OboeStream_setBufferSize(OboeStream stream, oboe_size_frames_t frames);
401
402/**
403 * Query the maximum number of frames that can be filled without blocking.
Phil Burk5a7bdb22016-11-22 15:52:04 -0800404 *
405 * @param stream handle provided by OboeStreamBuilder_openStream()
406 * @param frames pointer to variable to receive the buffer size
Phil Burkab177962016-11-18 17:11:59 -0800407 * @return OBOE_OK or a negative error.
408 */
409oboe_result_t OboeStream_getBufferSize(OboeStream stream, oboe_size_frames_t *frames);
410
411/**
412 * Query the number of frames that are read or written by the endpoint at one time.
Phil Burk5a7bdb22016-11-22 15:52:04 -0800413 *
414 * @param stream handle provided by OboeStreamBuilder_openStream()
415 * @param frames pointer to variable to receive the burst size
Phil Burkab177962016-11-18 17:11:59 -0800416 * @return OBOE_OK or a negative error.
417 */
418oboe_result_t OboeStream_getFramesPerBurst(OboeStream stream, oboe_size_frames_t *frames);
419
420/**
421 * Query maximum buffer capacity in frames.
Phil Burk5a7bdb22016-11-22 15:52:04 -0800422 *
423 * @param stream handle provided by OboeStreamBuilder_openStream()
424 * @param frames pointer to variable to receive the buffer capacity
Phil Burkab177962016-11-18 17:11:59 -0800425 * @return OBOE_OK or a negative error.
426 */
427oboe_result_t OboeStream_getBufferCapacity(OboeStream stream, oboe_size_frames_t *frames);
428
429/**
430 * An XRun is an Underrun or an Overrun.
431 * During playing, an underrun will occur if the stream is not written in time
432 * and the system runs out of valid data.
433 * During recording, an overrun will occur if the stream is not read in time
434 * and there is no place to put the incoming data so it is discarded.
435 *
436 * An underrun or overrun can cause an audible "pop" or "glitch".
437 *
Phil Burk5a7bdb22016-11-22 15:52:04 -0800438 * @param stream handle provided by OboeStreamBuilder_openStream()
439 * @param xRunCount pointer to variable to receive the underrun or overrun count
Phil Burkab177962016-11-18 17:11:59 -0800440 * @return OBOE_OK or a negative error.
441 */
442oboe_result_t OboeStream_getXRunCount(OboeStream stream, int32_t *xRunCount);
443
444/**
Phil Burk5a7bdb22016-11-22 15:52:04 -0800445 * @param stream handle provided by OboeStreamBuilder_openStream()
446 * @param sampleRate pointer to variable to receive the actual sample rate
Phil Burkab177962016-11-18 17:11:59 -0800447 * @return OBOE_OK or a negative error.
448 */
449oboe_result_t OboeStream_getSampleRate(OboeStream stream, int32_t *sampleRate);
450
451/**
Phil Burk5a7bdb22016-11-22 15:52:04 -0800452 * The samplesPerFrame is also known as channelCount.
453 *
454 * @param stream handle provided by OboeStreamBuilder_openStream()
455 * @param samplesPerFrame pointer to variable to receive the actual samples per frame
Phil Burkab177962016-11-18 17:11:59 -0800456 * @return OBOE_OK or a negative error.
457 */
458oboe_result_t OboeStream_getSamplesPerFrame(OboeStream stream, int32_t *samplesPerFrame);
459
460/**
Phil Burk5a7bdb22016-11-22 15:52:04 -0800461 * @param stream handle provided by OboeStreamBuilder_openStream()
462 * @param format pointer to variable to receive the actual data format
Phil Burkab177962016-11-18 17:11:59 -0800463 * @return OBOE_OK or a negative error.
464 */
465oboe_result_t OboeStream_getFormat(OboeStream stream, oboe_audio_format_t *format);
466
467/**
468 * Provide actual sharing mode.
Phil Burk5a7bdb22016-11-22 15:52:04 -0800469 * @param stream handle provided by OboeStreamBuilder_openStream()
470 * @param sharingMode pointer to variable to receive the actual sharing mode
Phil Burkab177962016-11-18 17:11:59 -0800471 * @return OBOE_OK or a negative error.
472 */
473oboe_result_t OboeStream_getSharingMode(OboeStream stream,
474 oboe_sharing_mode_t *sharingMode);
475
476/**
477 * @param stream handle provided by OboeStreamBuilder_openStream()
478 * @param direction pointer to a variable to be set to the current direction.
479 * @return OBOE_OK or a negative error.
480 */
481oboe_result_t OboeStream_getDirection(OboeStream stream, uint32_t *direction);
482
483/**
484 * Passes back the number of frames that have been written since the stream was created.
485 * For an output stream, this will be advanced by the application calling write().
486 * For an input stream, this will be advanced by the device or service.
487 *
488 * The frame position is monotonically increasing.
489 *
Phil Burk5a7bdb22016-11-22 15:52:04 -0800490 * @param stream handle provided by OboeStreamBuilder_openStream()
491 * @param frames pointer to variable to receive the frames written
Phil Burkab177962016-11-18 17:11:59 -0800492 * @return OBOE_OK or a negative error.
493 */
494oboe_result_t OboeStream_getFramesWritten(OboeStream stream, oboe_position_frames_t *frames);
495
496/**
497 * Passes back the number of frames that have been read since the stream was created.
498 * For an output stream, this will be advanced by the device or service.
499 * For an input stream, this will be advanced by the application calling read().
500 *
501 * The frame position is monotonically increasing.
502 *
Phil Burk5a7bdb22016-11-22 15:52:04 -0800503 * @param stream handle provided by OboeStreamBuilder_openStream()
504 * @param frames pointer to variable to receive the frames written
Phil Burkab177962016-11-18 17:11:59 -0800505 * @return OBOE_OK or a negative error.
506 */
507oboe_result_t OboeStream_getFramesRead(OboeStream stream, oboe_position_frames_t *frames);
508
509/**
510 * Passes back the time at which a particular frame was presented.
511 * This can be used to synchronize audio with video or MIDI.
512 * It can also be used to align a recorded stream with a playback stream.
513 *
Phil Burk5a7bdb22016-11-22 15:52:04 -0800514 * Timestamps are only valid when the stream is in OBOE_STREAM_STATE_STARTED.
Phil Burkab177962016-11-18 17:11:59 -0800515 * OBOE_ERROR_INVALID_STATE will be returned if the stream is not started.
516 * Note that because requestStart() is asynchronous, timestamps will not be valid until
517 * a short time after calling requestStart().
518 * So OBOE_ERROR_INVALID_STATE should not be considered a fatal error.
519 * Just try calling again later.
520 *
521 * If an error occurs, then the position and time will not be modified.
522 *
523 * The position and time passed back are monotonically increasing.
524 *
525 * @param stream A handle provided by OboeStreamBuilder_openStream()
526 * @param clockId OBOE_CLOCK_MONOTONIC or OBOE_CLOCK_BOOTTIME
527 * @param framePosition pointer to a variable to receive the position
528 * @param timeNanoseconds pointer to a variable to receive the time
529 * @return OBOE_OK or a negative error
530 */
531oboe_result_t OboeStream_getTimestamp(OboeStream stream,
532 oboe_clockid_t clockid,
533 oboe_position_frames_t *framePosition,
534 oboe_nanoseconds_t *timeNanoseconds);
535
536#endif //NATIVEOBOE_OBOEAUDIO_H