Skip to content

Commit

Permalink
oboe: add ErrorOrValue dual return
Browse files Browse the repository at this point in the history
For returning an error code and a frame count, or other value, at the same time.
  • Loading branch information
Phil Burk authored and dturner committed Mar 27, 2018
1 parent 8b57536 commit 4cf25f1
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 25 deletions.
9 changes: 5 additions & 4 deletions include/oboe/AudioStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <cstdint>
#include <ctime>
#include "oboe/Definitions.h"
#include "oboe/ErrorOrValue.h"
#include "oboe/AudioStreamBuilder.h"
#include "oboe/AudioStreamBase.h"

Expand Down Expand Up @@ -174,16 +175,16 @@ class AudioStream : public AudioStreamBase {
* @param timeoutNanoseconds Maximum number of nanoseconds to wait for completion.
* @return The number of frames actually written or a negative error.
*/
virtual int32_t write(const void *buffer,
virtual ErrorOrValue<int32_t> write(const void *buffer,
int32_t numFrames,
int64_t timeoutNanoseconds) {
return static_cast<int32_t>(Result::ErrorUnimplemented);
return ErrorOrValue<int32_t>(Result::ErrorUnimplemented);
}

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

/**
Expand Down
58 changes: 58 additions & 0 deletions include/oboe/ErrorOrValue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef OBOE_ERROR_OR_VALUE_H
#define OBOE_ERROR_OR_VALUE_H

#include "oboe/Definitions.h"

namespace oboe {

template <typename T>
class ErrorOrValue {
public:
explicit ErrorOrValue(oboe::Result error)
: mValue{}
, mError(error) {}

explicit ErrorOrValue(T value)
: mValue(value < 0 ? 0 : value)
, mError(value < 0 ? static_cast<Result>(value) : oboe::Result::OK) {}

oboe::Result error() const {
return mError;
}

T value() const {
return mValue;
}

/**
* Quick way to check for an error.
* @return true if an error occurred // TODO does this seem backwards?
*/
explicit operator bool() const { return mError != oboe::Result::OK; }

bool operator !() const { return mError == oboe::Result::OK; }

private:
const T mValue;
const oboe::Result mError;
};

} // namespace oboe

#endif //OBOE_ERROR_OR_VALUE_H
1 change: 1 addition & 0 deletions include/oboe/Oboe.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define OBOE_OBOE_H

#include "oboe/Definitions.h"
#include "oboe/ErrorOrValue.h"
#include "oboe/LatencyTuner.h"
#include "oboe/AudioStream.h"
#include "oboe/AudioStreamBase.h"
Expand Down
16 changes: 10 additions & 6 deletions src/aaudio/AudioStreamAAudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,25 +265,29 @@ Result AudioStreamAAudio::requestStop() {
}

// TODO: Update to return tuple of Result and framesWritten (avoids cast)
int32_t AudioStreamAAudio::write(const void *buffer,
ErrorOrValue<int32_t> AudioStreamAAudio::write(const void *buffer,
int32_t numFrames,
int64_t timeoutNanoseconds) {
AAudioStream *stream = mAAudioStream.load();
if (stream != nullptr) {
return mLibLoader->stream_write(mAAudioStream, buffer, numFrames, timeoutNanoseconds);
int32_t result = mLibLoader->stream_write(mAAudioStream, buffer,
numFrames, timeoutNanoseconds);
return ErrorOrValue<int32_t>(result);
} else {
return static_cast<int32_t>(Result::ErrorNull);
return ErrorOrValue<int32_t>(Result::ErrorNull);
}
}

int32_t AudioStreamAAudio::read(void *buffer,
ErrorOrValue<int32_t> AudioStreamAAudio::read(void *buffer,
int32_t numFrames,
int64_t timeoutNanoseconds) {
AAudioStream *stream = mAAudioStream.load();
if (stream != nullptr) {
return mLibLoader->stream_read(mAAudioStream, buffer, numFrames, timeoutNanoseconds);
int32_t result = mLibLoader->stream_read(mAAudioStream, buffer,
numFrames, timeoutNanoseconds);
return ErrorOrValue<int32_t>(result);
} else {
return static_cast<int32_t>(Result::ErrorNull);
return ErrorOrValue<int32_t>(Result::ErrorNull);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/aaudio/AudioStreamAAudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ class AudioStreamAAudio : public AudioStream {
Result requestFlush() override;
Result requestStop() override;

int32_t write(const void *buffer,
ErrorOrValue<int32_t> write(const void *buffer,
int32_t numFrames,
int64_t timeoutNanoseconds) override;

int32_t read(void *buffer,
ErrorOrValue<int32_t> read(void *buffer,
int32_t numFrames,
int64_t timeoutNanoseconds) override;

Expand Down
24 changes: 14 additions & 10 deletions src/opensles/AudioStreamBuffered.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,23 +98,23 @@ int64_t AudioStreamBuffered::predictNextCallbackTime() {
// TODO: Consider returning an error_or_value struct instead.
// Common code for read/write.
// @return number of frames transferred or negative error
int32_t AudioStreamBuffered::transfer(void *buffer,
ErrorOrValue<int32_t> AudioStreamBuffered::transfer(void *buffer,
int32_t numFrames,
int64_t timeoutNanoseconds) {
// Validate arguments.
if (buffer == nullptr) {
LOGE("AudioStreamBuffered::%s(): buffer is NULL", __func__);
return (int32_t) Result ::ErrorNull;
return ErrorOrValue<int32_t>(Result ::ErrorNull);
}
if (numFrames < 0) {
LOGE("AudioStreamBuffered::%s(): numFrames is negative", __func__);
return (int32_t) Result::ErrorOutOfRange;
return ErrorOrValue<int32_t>(Result::ErrorOutOfRange);
} else if (numFrames == 0) {
return 0;
return ErrorOrValue<int32_t>(0);
}
if (timeoutNanoseconds < 0) {
LOGE("AudioStreamBuffered::%s(): timeoutNanoseconds is negative", __func__);
return (int32_t) Result ::ErrorOutOfRange;
return ErrorOrValue<int32_t>(Result::ErrorOutOfRange);
}

int32_t result = 0;
Expand Down Expand Up @@ -175,25 +175,29 @@ int32_t AudioStreamBuffered::transfer(void *buffer,
}
} while(repeat);

return result < 0 ? result : (numFrames - framesLeft);
if (result < 0) {
return ErrorOrValue<int32_t>(static_cast<Result>(result));
} else {
return ErrorOrValue<int32_t>((numFrames - framesLeft));
}
}

// Write to the FIFO so the callback can read from it.
int32_t AudioStreamBuffered::write(const void *buffer,
ErrorOrValue<int32_t> AudioStreamBuffered::write(const void *buffer,
int32_t numFrames,
int64_t timeoutNanoseconds) {
if (getDirection() == Direction::Input) {
return (int32_t) Result::ErrorUnavailable; // TODO review, better error code?
return ErrorOrValue<int32_t>(Result::ErrorUnavailable); // TODO review, better error code?
}
return transfer((void *) buffer, numFrames, timeoutNanoseconds);
}

// Read data from the FIFO that was written by the callback.
int32_t AudioStreamBuffered::read(void *buffer,
ErrorOrValue<int32_t> AudioStreamBuffered::read(void *buffer,
int32_t numFrames,
int64_t timeoutNanoseconds) {
if (getDirection() == Direction::Output) {
return (int32_t) Result::ErrorUnavailable; // TODO review, better error code?
return ErrorOrValue<int32_t>(Result::ErrorUnavailable); // TODO review, better error code?
}
return transfer(buffer, numFrames, timeoutNanoseconds);
}
Expand Down
6 changes: 3 additions & 3 deletions src/opensles/AudioStreamBuffered.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ class AudioStreamBuffered : public AudioStream {
void allocateFifo();


int32_t write(const void *buffer,
ErrorOrValue<int32_t> write(const void *buffer,
int32_t numFrames,
int64_t timeoutNanoseconds) override;

int32_t read(void *buffer,
ErrorOrValue<int32_t> read(void *buffer,
int32_t numFrames,
int64_t timeoutNanoseconds) override;

Expand Down Expand Up @@ -74,7 +74,7 @@ class AudioStreamBuffered : public AudioStream {
void markCallbackTime(int numFrames);

// Read or write to the FIFO.
int32_t transfer(void *buffer, int32_t numFrames, int64_t timeoutNanoseconds);
ErrorOrValue<int32_t> transfer(void *buffer, int32_t numFrames, int64_t timeoutNanoseconds);

void incrementXRunCount() {
mXRunCount++;
Expand Down

0 comments on commit 4cf25f1

Please sign in to comment.