Move dead submodules in-tree

Signed-off-by: swurl <swurl@swurl.xyz>
This commit is contained in:
swurl 2025-05-31 02:33:02 -04:00
parent c0cceff365
commit 6c655321e6
No known key found for this signature in database
GPG key ID: A5A7629F109C8FD1
4081 changed files with 1185566 additions and 45 deletions

View file

@ -0,0 +1,132 @@
/*
* Copyright 2019 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 SAMPLES_DEFAULT_DATA_CALLBACK_H
#define SAMPLES_DEFAULT_DATA_CALLBACK_H
#include <vector>
#include <oboe/AudioStreamCallback.h>
#include <logging_macros.h>
#include "IRenderableAudio.h"
#include "IRestartable.h"
/**
* This is a callback object which will render data from an `IRenderableAudio` source.
*/
class DefaultDataCallback : public oboe::AudioStreamDataCallback {
public:
DefaultDataCallback() {}
virtual ~DefaultDataCallback() = default;
virtual oboe::DataCallbackResult
onAudioReady(oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames) override {
if (mIsThreadAffinityEnabled && !mIsThreadAffinitySet) {
setThreadAffinity();
mIsThreadAffinitySet = true;
}
float *outputBuffer = static_cast<float *>(audioData);
std::shared_ptr<IRenderableAudio> localRenderable = mRenderable;
if (!localRenderable) {
LOGE("Renderable source not set!");
return oboe::DataCallbackResult::Stop;
}
localRenderable->renderAudio(outputBuffer, numFrames);
return oboe::DataCallbackResult::Continue;
}
void setSource(std::shared_ptr<IRenderableAudio> renderable) {
mRenderable = renderable;
}
/**
* Reset the callback to its initial state.
*/
void reset(){
mIsThreadAffinitySet = false;
}
std::shared_ptr<IRenderableAudio> getSource() {
return mRenderable;
}
/**
* Set the CPU IDs to bind the audio callback thread to
*
* @param mCpuIds - the CPU IDs to bind to
*/
void setCpuIds(std::vector<int> cpuIds){
mCpuIds = std::move(cpuIds);
}
/**
* Enable or disable binding the audio callback thread to specific CPU cores. The CPU core IDs
* can be specified using @see setCpuIds. If no CPU IDs are specified the initial core which the
* audio thread is called on will be used.
*
* @param isEnabled - whether the audio callback thread should be bound to specific CPU core(s)
*/
void setThreadAffinityEnabled(bool isEnabled){
mIsThreadAffinityEnabled = isEnabled;
LOGD("Thread affinity enabled: %s", (isEnabled) ? "true" : "false");
}
private:
std::shared_ptr<IRenderableAudio> mRenderable;
std::vector<int> mCpuIds; // IDs of CPU cores which the audio callback should be bound to
std::atomic<bool> mIsThreadAffinityEnabled { false };
std::atomic<bool> mIsThreadAffinitySet { false };
/**
* Set the thread affinity for the current thread to mCpuIds. This can be useful to call on the
* audio thread to avoid underruns caused by CPU core migrations to slower CPU cores.
*/
void setThreadAffinity() {
pid_t current_thread_id = gettid();
cpu_set_t cpu_set;
CPU_ZERO(&cpu_set);
// If the callback cpu ids aren't specified then bind to the current cpu
if (mCpuIds.empty()) {
int current_cpu_id = sched_getcpu();
LOGD("Binding to current CPU ID %d", current_cpu_id);
CPU_SET(current_cpu_id, &cpu_set);
} else {
LOGD("Binding to %d CPU IDs", static_cast<int>(mCpuIds.size()));
for (size_t i = 0; i < mCpuIds.size(); i++) {
int cpu_id = mCpuIds.at(i);
LOGD("CPU ID %d added to cores set", cpu_id);
CPU_SET(cpu_id, &cpu_set);
}
}
int result = sched_setaffinity(current_thread_id, sizeof(cpu_set_t), &cpu_set);
if (result == 0) {
LOGV("Thread affinity set");
} else {
LOGW("Error setting thread affinity. Error no: %d", result);
}
mIsThreadAffinitySet = true;
}
};
#endif //SAMPLES_DEFAULT_DATA_CALLBACK_H

View file

@ -0,0 +1,56 @@
/*
* Copyright 2020 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 SAMPLES_DEFAULT_ERROR_CALLBACK_H
#define SAMPLES_DEFAULT_ERROR_CALLBACK_H
#include <vector>
#include <oboe/AudioStreamCallback.h>
#include <logging_macros.h>
#include "IRestartable.h"
/**
* This is a callback object which will be called when a stream error occurs.
*
* It is constructed using an `IRestartable` which allows it to automatically restart the parent
* object if the stream is disconnected (for example, when headphones are attached).
*
* @param IRestartable - the object which should be restarted when the stream is disconnected
*/
class DefaultErrorCallback : public oboe::AudioStreamErrorCallback {
public:
DefaultErrorCallback(IRestartable &parent): mParent(parent) {}
virtual ~DefaultErrorCallback() = default;
virtual void onErrorAfterClose(oboe::AudioStream *oboeStream, oboe::Result error) override {
// Restart the stream if the error is a disconnect, otherwise do nothing and log the error
// reason.
if (error == oboe::Result::ErrorDisconnected) {
LOGI("Restarting AudioStream");
mParent.restart();
}
LOGE("Error was %s", oboe::convertToText(error));
}
private:
IRestartable &mParent;
};
#endif //SAMPLES_DEFAULT_ERROR_CALLBACK_H

View file

@ -0,0 +1,31 @@
/*
* Copyright 2018 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 SAMPLES_IRENDERABLEAUDIO_H
#define SAMPLES_IRENDERABLEAUDIO_H
#include <cstdint>
#include <string>
class IRenderableAudio {
public:
virtual ~IRenderableAudio() = default;
virtual void renderAudio(float *audioData, int32_t numFrames) = 0;
};
#endif //SAMPLES_IRENDERABLEAUDIO_H

View file

@ -0,0 +1,28 @@
/*
* Copyright 2018 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 SAMPLES_IRESTARTABLE_H
#define SAMPLES_IRESTARTABLE_H
/**
* Represents an object which can be restarted. For example an audio engine which has one or more
* streams which can be restarted following a change in audio device configuration. For example,
* headphones being connected.
*/
class IRestartable {
public:
virtual void restart() = 0;
};
#endif //SAMPLES_IRESTARTABLE_H

View file

@ -0,0 +1,25 @@
/*
* Copyright 2019 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 SAMPLES_ITAPPABLE_H
#define SAMPLES_ITAPPABLE_H
class ITappable {
public:
virtual ~ITappable() = default;
virtual void tap(bool isDown) = 0;
};
#endif //SAMPLES_ITAPPABLE_H

70
externals/oboe/samples/shared/Mixer.h vendored Normal file
View file

@ -0,0 +1,70 @@
/*
* Copyright 2018 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 SHARED_MIXER_H
#define SHARED_MIXER_H
#include <array>
#include "IRenderableAudio.h"
/**
* A Mixer object which sums the output from multiple tracks into a single output. The number of
* input channels on each track must match the number of output channels (default 1=mono). This can
* be changed by calling `setChannelCount`.
* The inputs to the mixer are not owned by the mixer, they should not be deleted while rendering.
*/
class Mixer : public IRenderableAudio {
public:
void renderAudio(float *audioData, int32_t numFrames) {
int numSamples = numFrames * mChannelCount;
if (numSamples > mBufferSize) {
mMixingBuffer = std::make_unique<float[]>(numSamples);
mBufferSize = numSamples;
}
// Zero out the incoming container array
memset(audioData, 0, sizeof(float) * numSamples);
for (int i = 0; i < mTracks.size(); ++i) {
mTracks[i]->renderAudio(mMixingBuffer.get(), numFrames);
for (int j = 0; j < numSamples; ++j) {
audioData[j] += mMixingBuffer[j];
}
}
}
void addTrack(IRenderableAudio *renderer){
mTracks.push_back(renderer);
}
void setChannelCount(int32_t channelCount){ mChannelCount = channelCount; }
void removeAllTracks(){
mTracks.clear();
}
private:
int32_t mBufferSize = 0;
std::unique_ptr<float[]> mMixingBuffer;
std::vector<IRenderableAudio*> mTracks;
int32_t mChannelCount = 1; // Default to mono
};
#endif //SHARED_MIXER_H

View file

@ -0,0 +1,49 @@
/*
* Copyright 2018 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 SHARED_MONOTOSTEREO_H
#define SHARED_MONOTOSTEREO_H
#include "IRenderableAudio.h"
class MonoToStereo : public IRenderableAudio {
public:
MonoToStereo(IRenderableAudio *input) : mInput(input){};
void renderAudio(float *audioData, int32_t numFrames) override {
constexpr int kChannelCountStereo = 2;
mInput->renderAudio(audioData, numFrames);
// We assume that audioData has sufficient frames to hold the stereo output, so copy each
// frame in the input to the output twice, working our way backwards through the input array
// e.g. 123 => 112233
for (int i = numFrames - 1; i >= 0; --i) {
audioData[i * kChannelCountStereo] = audioData[i];
audioData[i * kChannelCountStereo + 1] = audioData[i];
}
}
IRenderableAudio *mInput;
};
#endif //SHARED_MONOTOSTEREO_H

View file

@ -0,0 +1,94 @@
/*
* Copyright 2018 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 SHARED_OSCILLATOR_H
#define SHARED_OSCILLATOR_H
#include <cstdint>
#include <atomic>
#include <math.h>
#include <memory>
#include "IRenderableAudio.h"
constexpr double kDefaultFrequency = 440.0;
constexpr int32_t kDefaultSampleRate = 48000;
constexpr double kPi = M_PI;
constexpr double kTwoPi = kPi * 2;
class Oscillator : public IRenderableAudio {
public:
~Oscillator() = default;
void setWaveOn(bool isWaveOn) {
mIsWaveOn.store(isWaveOn);
};
void setSampleRate(int32_t sampleRate) {
mSampleRate = sampleRate;
updatePhaseIncrement();
};
void setFrequency(double frequency) {
mFrequency = frequency;
updatePhaseIncrement();
};
inline void setAmplitude(float amplitude) {
mAmplitude = amplitude;
};
// From IRenderableAudio
void renderAudio(float *audioData, int32_t numFrames) override {
if (mIsWaveOn){
for (int i = 0; i < numFrames; ++i) {
// Sine wave (sinf)
//audioData[i] = sinf(mPhase) * mAmplitude;
// Square wave
if (mPhase <= kPi){
audioData[i] = -mAmplitude;
} else {
audioData[i] = mAmplitude;
}
mPhase += mPhaseIncrement;
if (mPhase > kTwoPi) mPhase -= kTwoPi;
}
} else {
memset(audioData, 0, sizeof(float) * numFrames);
}
};
private:
std::atomic<bool> mIsWaveOn { false };
float mPhase = 0.0;
std::atomic<float> mAmplitude { 0 };
std::atomic<double> mPhaseIncrement { 0.0 };
double mFrequency = kDefaultFrequency;
int32_t mSampleRate = kDefaultSampleRate;
void updatePhaseIncrement(){
mPhaseIncrement.store((kTwoPi * mFrequency) / static_cast<double>(mSampleRate));
};
};
#endif //SHARED_OSCILLATOR_H

View file

@ -0,0 +1,109 @@
/*
* Copyright 2018 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 SHARED_SYNTH_SOUND_H
#define SHARED_SYNTH_SOUND_H
#include <cstdint>
#include <atomic>
#include <math.h>
#include <memory>
#include "IRenderableAudio.h"
constexpr float kDefaultFrequency = 440.0;
constexpr int32_t kDefaultSampleRate = 48000;
constexpr float kPi = M_PI;
constexpr float kTwoPi = kPi * 2;
constexpr int32_t kNumSineWaves = 5;
constexpr float kSustainMultiplier = 0.99999;
constexpr float kReleaseMultiplier = 0.999;
// Stop playing music below this cutoff
constexpr float kMasterAmplitudeCutOff = 0.01;
class SynthSound : public IRenderableAudio {
public:
SynthSound() {
}
~SynthSound() {
};
void noteOn() {
mTrigger = true; // start a note envelope
mAmplitudeScaler = kSustainMultiplier;
}
void noteOff() {
mAmplitudeScaler = kReleaseMultiplier;
}
void setSampleRate(int32_t sampleRate) {
mSampleRate = sampleRate;
updatePhaseIncrement();
};
void setFrequency(float frequency) {
mFrequency = frequency;
updatePhaseIncrement();
};
// Amplitudes from https://epubs.siam.org/doi/pdf/10.1137/S00361445003822
inline void setAmplitude(float amplitude) {
mAmplitudes[0] = amplitude * .2f;
mAmplitudes[1] = amplitude;
mAmplitudes[2] = amplitude * .1f;
mAmplitudes[3] = amplitude * .02f;
mAmplitudes[4] = amplitude * .15f;
};
// From IRenderableAudio
void renderAudio(float *audioData, int32_t numFrames) override {
for (int i = 0; i < numFrames; ++i) {
if (mTrigger.exchange(false)) {
mMasterAmplitude = 1.0;
mPhase = 0.0f;
} else {
mMasterAmplitude *= mAmplitudeScaler;
}
audioData[i] = 0;
if (mMasterAmplitude < kMasterAmplitudeCutOff) {
continue;
}
for (int j = 0; j < kNumSineWaves; ++j) {
audioData[i] += sinf(mPhase * (j + 1)) * mAmplitudes[j] * mMasterAmplitude;
}
mPhase += mPhaseIncrement;
if (mPhase > kTwoPi) {
mPhase -= kTwoPi;
}
}
};
private:
std::atomic<bool> mTrigger { false };
float mMasterAmplitude = 0.0f;
std::atomic<float> mAmplitudeScaler { 0.0f };
std::array<std::atomic<float>, kNumSineWaves> mAmplitudes;
float mPhase = 0.0f;
std::atomic<float> mPhaseIncrement { 0 };
std::atomic<float> mFrequency { kDefaultFrequency };
std::atomic<int32_t> mSampleRate { kDefaultSampleRate };
void updatePhaseIncrement(){
// Note how there is a division here. If this file is changed so that updatePhaseIncrement
// is called more frequently, please cache 1/mSampleRate. This allows this operation to not
// need divisions.
mPhaseIncrement = kTwoPi * mFrequency / static_cast<float>(mSampleRate);
};
};
#endif //SHARED_SYNTH_SOUND_H

View file

@ -0,0 +1,38 @@
/*
* Copyright 2019 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 SAMPLES_RENDERABLE_TAP_H
#define SAMPLES_RENDERABLE_TAP_H
#include <stdint.h>
#include "IRenderableAudio.h"
#include "ITappable.h"
/**
* This class renders Float audio, but can be tapped to control.
* It also contains members for sample rate and channel count
*/
class TappableAudioSource : public IRenderableAudio, public ITappable {
public:
TappableAudioSource(int32_t sampleRate, int32_t channelCount) :
mSampleRate(sampleRate), mChannelCount(channelCount) { }
int32_t mSampleRate;
int32_t mChannelCount;
};
#endif //SAMPLES_RENDERABLE_TAP_H