Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New namespace, constexprs and scoped enums #18

Merged
merged 11 commits into from Dec 1, 2017
28 changes: 26 additions & 2 deletions CMakeLists.txt
Expand Up @@ -5,8 +5,32 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -std=c++11")
# Specify directories which the compiler should look for headers
include_directories(
include
src)
src
)

file(GLOB_RECURSE oboe_sources src/*)
set (oboe_sources
include/oboe/LatencyTuner.h
include/oboe/Definitions.h
include/oboe/AudioStream.h
include/oboe/AudioStreamBase.h
include/oboe/AudioStreamBuilder.h
include/oboe/AudioStreamCallback.h
include/oboe/Utilities.h
src/aaudio/AAudioLoader.cpp
src/aaudio/AudioStreamAAudio.cpp
src/common/AudioClock.h
src/common/OboeDebug.h
src/common/LatencyTuner.cpp
src/common/AudioStream.cpp
src/common/AudioStreamBuilder.cpp
src/common/Utilities.cpp
src/fifo/FifoBuffer.cpp
src/fifo/FifoController.cpp
src/fifo/FifoControllerBase.cpp
src/fifo/FifoControllerIndirect.cpp
src/opensles/AudioStreamBuffered.cpp
src/opensles/AudioStreamOpenSLES.cpp
src/opensles/OpenSLESUtilities.cpp
)

add_library(oboe STATIC ${oboe_sources})
132 changes: 66 additions & 66 deletions FullGuide.md

Large diffs are not rendered by default.

36 changes: 18 additions & 18 deletions GettingStarted.md
Expand Up @@ -48,24 +48,24 @@ Include the Oboe header:

#include <oboe/Oboe.h>

Streams are built using an `OboeStreamBuilder`. Create one like this:
Streams are built using an `AudioStreamBuilder`. Create one like this:

OboeStreamBuilder builder;
oboe::AudioStreamBuilder builder;

Use the builder's set methods to set properties on the stream (you can read more about these properties in the [full guide](FullGuide.md)):

builder.setDirection(OBOE_DIRECTION_OUTPUT);
builder.setPerformanceMode(OBOE_PERFORMANCE_MODE_LOW_LATENCY);
builder.setSharingMode(OBOE_SHARING_MODE_EXCLUSIVE);
builder.setDirection(oboe::Direction::Output);
builder.setPerformanceMode(oboe::PerformanceMode::LowLatency);
builder.setSharingMode(oboe::SharingMode::Exclusive);

Define an `OboeStreamCallback` class to receive callbacks whenever the stream requires new data.
Define an `AudioStreamCallback` class to receive callbacks whenever the stream requires new data.

class MyCallback : public OboeStreamCallback {
class MyCallback : public oboe::AudioStreamCallback {
public:
oboe_data_callback_result_t
onAudioReady(OboeStream *audioStream, void *audioData, int32_t numFrames){
oboe::Result
onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames){
generateSineWave(static_cast<float *>(audioData), numFrames);
return OBOE_CALLBACK_RESULT_CONTINUE;
return oboe::DataCallbackResult::Continue;
}
};

Expand All @@ -76,21 +76,21 @@ Supply this callback class to the builder:

Open the stream:

OboeStream *stream;
oboe_result_t result = builder.openStream(&stream);
oboe::AudioStream *stream;
oboe::Result result = builder.openStream(&stream);

Check the result to make sure the stream was opened successfully. Oboe has many convenience methods for converting its types into human-readable strings, they all start with `Oboe_convert`:
Check the result to make sure the stream was opened successfully. Oboe has many convenience methods for converting its types into human-readable strings, they all start with `oboe::convert`:

if (result != OBOE_OK){
LOGE("Failed to create stream. Error: %s", Oboe_convertResultToText(result));
if (result != Result::OK){
LOGE("Failed to create stream. Error: %s", oboe::convertResultToText(result));
}

Note that this sample code uses the [logging macros from here](https://github.com/googlesamples/android-audio-high-performance/blob/master/debug-utils/logging_macros.h).

Check the properties of the created stream. The **format** is one property which you should check. The default is `float` on API 21+ and `int16_t` on API 20 or lower. This will dictate the `audioData` type in the `OboeStreamCallback::onAudioReady` callback.
Check the properties of the created stream. The **format** is one property which you should check. The default is `float` on API 21+ and `int16_t` on API 20 or lower. This will dictate the `audioData` type in the `AudioStreamCallback::onAudioReady` callback.

oboe_audio_format_t format = stream->getFormat();
LOGI("Stream format is %s", Oboe_convertAudioFormatToText(format));
oboe::AudioFormat format = stream->getFormat();
LOGI("AudioStream format is %s", oboe::convertAudioFormatToText(format));

Now start the stream.

Expand Down
4 changes: 2 additions & 2 deletions build_all_android.sh
Expand Up @@ -122,8 +122,8 @@ build_oboe mips
printf "%s\r\n" "example: |" >> ${CDEP_MANIFEST_FILE}
printf "%s\r\n" " #include <oboe/Oboe.h>" >> ${CDEP_MANIFEST_FILE}
printf "%s\r\n" " void openStream() {" >> ${CDEP_MANIFEST_FILE}
printf "%s\r\n" " OboeStreamBuilder builder;" >> ${CDEP_MANIFEST_FILE}
printf "%s\r\n" " OboeStream *stream;" >> ${CDEP_MANIFEST_FILE}
printf "%s\r\n" " AudioStreamBuilder builder;" >> ${CDEP_MANIFEST_FILE}
printf "%s\r\n" " AudioStream *stream;" >> ${CDEP_MANIFEST_FILE}
printf "%s\r\n" " builder.openStream(&stream);" >> ${CDEP_MANIFEST_FILE}
printf "%s\r\n" " }" >> ${CDEP_MANIFEST_FILE}

Expand Down
107 changes: 53 additions & 54 deletions include/oboe/OboeStream.h → include/oboe/AudioStream.h
Expand Up @@ -14,31 +14,31 @@
* limitations under the License.
*/

#ifndef OBOE_OBOE_STREAM_H_
#define OBOE_OBOE_STREAM_H_
#ifndef OBOE_STREAM_H_
#define OBOE_STREAM_H_

#include <stdint.h>
#include <time.h>
#include "oboe/OboeDefinitions.h"
#include "oboe/OboeStreamCallback.h"
#include "oboe/OboeStreamBase.h"
#include <cstdint>
#include <ctime>
#include "oboe/Definitions.h"
#include "oboe/AudioStreamBuilder.h"
#include "oboe/AudioStreamBase.h"

/** WARNING - UNDER CONSTRUCTION - THIS API WILL CHANGE. */

class OboeStreamBuilder;
namespace oboe {

#define DEFAULT_TIMEOUT_NANOS (2000 * OBOE_NANOS_PER_MILLISECOND)
constexpr int64_t kDefaultTimeoutNanos = (2000 * kNanosPerMillisecond);

/**
* Base class for Oboe C++ audio stream.
*/
class OboeStream : public OboeStreamBase {
class AudioStream : public AudioStreamBase {
public:

OboeStream() {}
explicit OboeStream(const OboeStreamBuilder &builder);
AudioStream() {}
explicit AudioStream(const AudioStreamBuilder &builder);

virtual ~OboeStream() = default;
virtual ~AudioStream() = default;

/**
* Open a stream based on the current settings.
Expand All @@ -48,35 +48,35 @@ class OboeStream : public OboeStreamBase {
*
* @return
*/
virtual oboe_result_t open();
virtual Result open();

/**
* Close the stream and deallocate any resources from the open() call.
*/
virtual oboe_result_t close() = 0;
virtual Result close() = 0;

/*
* These are synchronous and will block until the operation is complete.
*/
virtual oboe_result_t start(int64_t timeoutNanoseconds = DEFAULT_TIMEOUT_NANOS);
virtual oboe_result_t pause(int64_t timeoutNanoseconds = DEFAULT_TIMEOUT_NANOS);
virtual oboe_result_t flush(int64_t timeoutNanoseconds = DEFAULT_TIMEOUT_NANOS);
virtual oboe_result_t stop(int64_t timeoutNanoseconds = DEFAULT_TIMEOUT_NANOS);
virtual Result start(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);
virtual Result pause(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);
virtual Result flush(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);
virtual Result stop(int64_t timeoutNanoseconds = kDefaultTimeoutNanos);

/* Asynchronous requests.
* Use waitForStateChange() if you need to wait for completion.
*/
virtual oboe_result_t requestStart() = 0;
virtual oboe_result_t requestPause() = 0;
virtual oboe_result_t requestFlush() = 0;
virtual oboe_result_t requestStop() = 0;
virtual Result requestStart() = 0;
virtual Result requestPause() = 0;
virtual Result requestFlush() = 0;
virtual Result requestStop() = 0;

/**
* Query the current state, eg. OBOE_STREAM_STATE_PAUSING
* Query the current state, eg. StreamState::Pausing
*
* @return state or a negative error.
*/
virtual oboe_stream_state_t getState() = 0;
virtual StreamState getState() = 0;

/**
* Wait until the current state no longer matches the input state.
Expand All @@ -87,9 +87,9 @@ class OboeStream : public OboeStreamBase {
* an advanced technique.
*
* <pre><code>
* int64_t timeoutNanos = 500 * OBOE_NANOS_PER_MILLISECOND; // arbitrary 1/2 second
* oboe_stream_state_t currentState = stream->getState(stream);
* while (currentState >= 0 && currentState != OBOE_STREAM_STATE_PAUSED) {
* int64_t timeoutNanos = 500 * kNanosPerMillisecond; // arbitrary 1/2 second
* StreamState currentState = stream->getState(stream);
* while (currentState >= 0 && currentState != StreamState::Paused) {
* currentState = stream->waitForStateChange(
* stream, currentState, timeoutNanos);
* }
Expand All @@ -99,14 +99,12 @@ class OboeStream : public OboeStreamBase {
* @param currentState The state we want to avoid.
* @param nextState Pointer to a variable that will be set to the new state.
* @param timeoutNanoseconds The maximum time to wait in nanoseconds.
* @return OBOE_OK or a negative error.
* @return Result::OK or a Result::Error.
*/
virtual oboe_result_t waitForStateChange(oboe_stream_state_t currentState,
oboe_stream_state_t *nextState,
virtual Result waitForStateChange(StreamState currentState,
StreamState *nextState,
int64_t timeoutNanoseconds) = 0;



/**
* This can be used to adjust the latency of the buffer by changing
* the threshold where blocking will occur.
Expand All @@ -116,10 +114,10 @@ class OboeStream : public OboeStreamBase {
* This cannot be set higher than getBufferCapacity().
*
* @param requestedFrames requested number of frames that can be filled without blocking
* @return resulting buffer size in frames or a negative error
* @return resulting buffer size in frames or a Result::Error
*/
virtual oboe_result_t setBufferSizeInFrames(int32_t requestedFrames) {
return OBOE_ERROR_UNIMPLEMENTED;
virtual Result setBufferSizeInFrames(int32_t requestedFrames) {
return Result::ErrorUnimplemented;
}

/**
Expand All @@ -134,7 +132,7 @@ class OboeStream : public OboeStreamBase {
* @return the count or negative error.
*/
virtual int32_t getXRunCount() {
return OBOE_ERROR_UNIMPLEMENTED;
return static_cast<int32_t>(Result::ErrorUnimplemented);
}

/**
Expand All @@ -146,7 +144,7 @@ class OboeStream : public OboeStreamBase {

bool isPlaying();

OboeStreamCallback *getCallback() const { return mStreamCallback; }
std::shared_ptr<AudioStreamCallback> getCallback() const { return mStreamCallback; }

int32_t getBytesPerFrame() const { return mChannelCount * getBytesPerSample(); }

Expand All @@ -158,12 +156,12 @@ class OboeStream : public OboeStreamBase {
*/
virtual int64_t getFramesWritten() { return mFramesWritten; }

virtual int64_t getFramesRead() { return OBOE_ERROR_UNIMPLEMENTED; }
virtual int64_t getFramesRead() { return static_cast<int64_t>(Result::ErrorUnimplemented); }

virtual oboe_result_t getTimestamp(clockid_t clockId,
virtual Result getTimestamp(clockid_t clockId,
int64_t *framePosition,
int64_t *timeNanoseconds) {
return OBOE_ERROR_UNIMPLEMENTED;
return Result::ErrorUnimplemented;
}

// ============== I/O ===========================
Expand All @@ -177,16 +175,16 @@ class OboeStream : public OboeStreamBase {
* @param timeoutNanoseconds Maximum number of nanoseconds to wait for completion.
* @return The number of frames actually written or a negative error.
*/
virtual oboe_result_t write(const void *buffer,
virtual int32_t write(const void *buffer,
int32_t numFrames,
int64_t timeoutNanoseconds) {
return OBOE_ERROR_UNIMPLEMENTED;
return static_cast<int32_t>(Result::ErrorUnimplemented);
}

virtual oboe_result_t read(void *buffer,
virtual int32_t read(void *buffer,
int32_t numFrames,
int64_t timeoutNanoseconds) {
return OBOE_ERROR_UNIMPLEMENTED;
return static_cast<int32_t>(Result::ErrorUnimplemented);
}

/**
Expand All @@ -205,28 +203,29 @@ class OboeStream : public OboeStreamBase {

/**
* Wait for a transition from one state to another.
* @return OBOE_OK if the endingState was observed, or OBOE_ERROR_UNEXPECTED_STATE
* @return OK if the endingState was observed, or ErrorUnexpectedState
* if any state that was not the startingState or endingState was observed
* or OBOE_ERROR_TIMEOUT.
* or ErrorTimeout.
*/
virtual oboe_result_t waitForStateTransition(oboe_stream_state_t startingState,
oboe_stream_state_t endingState,
virtual Result waitForStateTransition(StreamState startingState,
StreamState endingState,
int64_t timeoutNanoseconds);

oboe_result_t fireCallback(void *audioData, int numFrames);
Result fireCallback(void *audioData, int numFrames);

virtual void setNativeFormat(oboe_audio_format_t format) {
virtual void setNativeFormat(AudioFormat format) {
mNativeFormat = format;
}

// TODO make private
// TODO: make private
// These do not change after open.
oboe_audio_format_t mNativeFormat = OBOE_AUDIO_FORMAT_INVALID;
AudioFormat mNativeFormat = AudioFormat::Invalid;

private:
int64_t mFramesWritten = 0;
int mPreviousScheduler = -1;
};

} // namespace oboe

#endif /* OBOE_OBOE_STREAM_H_ */
#endif /* OBOE_STREAM_H_ */