react-native-audio-api 0.8.1-nightly-2c9c6a6-20250903 → 0.8.1-nightly-da0ddc8-20250904
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +4 -0
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.h +10 -1
- package/android/src/main/cpp/audioapi/android/core/NativeAudioPlayer.hpp +36 -0
- package/android/src/main/java/com/swmansion/audioapi/core/NativeAudioPlayer.kt +24 -0
- package/android/src/main/java/com/swmansion/audioapi/system/LockScreenManager.kt +4 -4
- package/android/src/main/java/com/swmansion/audioapi/system/MediaNotificationManager.kt +78 -70
- package/android/src/main/java/com/swmansion/audioapi/system/MediaReceiver.kt +2 -1
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionCallback.kt +3 -11
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +57 -39
- package/android/src/main/res/drawable/logo.xml +16 -0
- package/common/cpp/audioapi/HostObjects/AudioContextHostObject.h +17 -23
- package/common/cpp/audioapi/HostObjects/AudioParamHostObject.h +4 -2
- package/common/cpp/audioapi/core/AudioParam.cpp +205 -254
- package/common/cpp/audioapi/core/AudioParam.h +98 -21
- package/common/cpp/audioapi/core/AudioParamEventQueue.cpp +65 -0
- package/common/cpp/audioapi/core/AudioParamEventQueue.h +63 -0
- package/common/cpp/audioapi/core/sources/StreamerNode.cpp +6 -5
- package/common/cpp/audioapi/core/sources/StreamerNode.h +5 -4
- package/common/cpp/audioapi/core/utils/ParamChangeEvent.cpp +2 -39
- package/common/cpp/audioapi/core/utils/ParamChangeEvent.h +53 -12
- package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.cpp +10 -0
- package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.h +10 -0
- package/common/cpp/audioapi/utils/CrossThreadEventScheduler.hpp +58 -0
- package/common/cpp/audioapi/utils/RingBiDirectionalBuffer.hpp +199 -0
- package/ios/audioapi/ios/system/AudioEngine.mm +1 -0
- package/lib/commonjs/plugin/withAudioAPI.js +1 -1
- package/lib/commonjs/plugin/withAudioAPI.js.map +1 -1
- package/lib/module/plugin/withAudioAPI.js +1 -1
- package/lib/module/plugin/withAudioAPI.js.map +1 -1
- package/package.json +1 -1
- package/src/plugin/withAudioAPI.ts +1 -1
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#include <audioapi/core/utils/ParamChangeEvent.h>
|
|
4
3
|
#include <audioapi/core/types/ParamChangeEventType.h>
|
|
4
|
+
#include <audioapi/core/utils/ParamChangeEvent.h>
|
|
5
5
|
#include <audioapi/utils/AudioBus.h>
|
|
6
6
|
#include <audioapi/core/AudioNode.h>
|
|
7
|
+
#include <audioapi/core/AudioParamEventQueue.h>
|
|
7
8
|
|
|
8
|
-
#include <
|
|
9
|
+
#include <cstddef>
|
|
10
|
+
#include <utility>
|
|
9
11
|
#include <memory>
|
|
10
12
|
#include <vector>
|
|
11
13
|
#include <unordered_set>
|
|
12
|
-
#include <
|
|
13
|
-
#include <mutex>
|
|
14
|
+
#include <audioapi/utils/CrossThreadEventScheduler.hpp>
|
|
14
15
|
|
|
15
16
|
namespace audioapi {
|
|
16
17
|
|
|
@@ -18,52 +19,128 @@ class AudioParam {
|
|
|
18
19
|
public:
|
|
19
20
|
explicit AudioParam(float defaultValue, float minValue, float maxValue, BaseAudioContext *context);
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
[[nodiscard]] float
|
|
22
|
+
/// JS-Thread only methods
|
|
23
|
+
/// These methods are called only from HostObjects invoked on the JS thread.
|
|
24
|
+
|
|
25
|
+
// JS-Thread only
|
|
26
|
+
[[nodiscard]] inline float getValue() const noexcept {
|
|
27
|
+
return value_;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// JS-Thread only
|
|
31
|
+
[[nodiscard]] inline float getDefaultValue() const noexcept {
|
|
32
|
+
return defaultValue_;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// JS-Thread only
|
|
36
|
+
[[nodiscard]] inline float getMinValue() const noexcept {
|
|
37
|
+
return minValue_;
|
|
38
|
+
}
|
|
26
39
|
|
|
27
|
-
|
|
40
|
+
// JS-Thread only
|
|
41
|
+
[[nodiscard]] inline float getMaxValue() const noexcept {
|
|
42
|
+
return maxValue_;
|
|
43
|
+
}
|
|
28
44
|
|
|
45
|
+
// JS-Thread only
|
|
46
|
+
inline void setValue(float value) {
|
|
47
|
+
value_ = std::clamp(value, minValue_, maxValue_);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// JS-Thread only
|
|
29
51
|
void setValueAtTime(float value, double startTime);
|
|
52
|
+
|
|
53
|
+
// JS-Thread only
|
|
30
54
|
void linearRampToValueAtTime(float value, double endTime);
|
|
55
|
+
|
|
56
|
+
// JS-Thread only
|
|
31
57
|
void exponentialRampToValueAtTime(float value, double endTime);
|
|
58
|
+
|
|
59
|
+
// JS-Thread only
|
|
32
60
|
void setTargetAtTime(float target, double startTime, double timeConstant);
|
|
61
|
+
|
|
62
|
+
// JS-Thread only
|
|
33
63
|
void setValueCurveAtTime(
|
|
34
|
-
|
|
64
|
+
std::shared_ptr<std::vector<float>> values,
|
|
35
65
|
size_t length,
|
|
36
66
|
double startTime,
|
|
37
67
|
double duration);
|
|
68
|
+
|
|
69
|
+
// JS-Thread only
|
|
38
70
|
void cancelScheduledValues(double cancelTime);
|
|
71
|
+
|
|
72
|
+
// JS-Thread only
|
|
39
73
|
void cancelAndHoldAtTime(double cancelTime);
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
/// Audio-Thread only methods
|
|
77
|
+
/// These methods are called only from the Audio rendering thread.
|
|
78
|
+
|
|
79
|
+
// Audio-Thread only (indirectly through AudioNode::connectParam by AudioNodeManager)
|
|
40
80
|
void addInputNode(AudioNode* node);
|
|
81
|
+
|
|
82
|
+
// Audio-Thread only (indirectly through AudioNode::disconnectParam by AudioNodeManager)
|
|
41
83
|
void removeInputNode(AudioNode* node);
|
|
84
|
+
|
|
85
|
+
// Audio-Thread only
|
|
42
86
|
std::shared_ptr<AudioBus> processARateParam(int framesToProcess, double time);
|
|
87
|
+
|
|
88
|
+
// Audio-Thread only
|
|
43
89
|
float processKRateParam(int framesToProcess, double time);
|
|
44
90
|
|
|
45
91
|
private:
|
|
92
|
+
// Core parameter state
|
|
93
|
+
BaseAudioContext *context_;
|
|
46
94
|
float value_;
|
|
47
95
|
float defaultValue_;
|
|
48
96
|
float minValue_;
|
|
49
97
|
float maxValue_;
|
|
50
|
-
BaseAudioContext *context_;
|
|
51
|
-
std::deque<ParamChangeEvent> eventsQueue_;
|
|
52
|
-
std::unordered_set<AudioNode *> inputNodes_;
|
|
53
|
-
std::shared_ptr<AudioBus> audioBus_;
|
|
54
|
-
std::mutex queueLock_;
|
|
55
98
|
|
|
99
|
+
AudioParamEventQueue eventsQueue_;
|
|
100
|
+
CrossThreadEventScheduler<AudioParam> eventScheduler_;
|
|
101
|
+
|
|
102
|
+
// Current automation state (cached for performance)
|
|
56
103
|
double startTime_;
|
|
57
104
|
double endTime_;
|
|
58
105
|
float startValue_;
|
|
59
106
|
float endValue_;
|
|
60
107
|
std::function<float(double, double, float, float, double)> calculateValue_;
|
|
61
|
-
std::vector<std::shared_ptr<AudioBus>> inputBuses_ = {};
|
|
62
108
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
109
|
+
// Input modulation system
|
|
110
|
+
std::vector<AudioNode *> inputNodes_;
|
|
111
|
+
std::shared_ptr<AudioBus> audioBus_;
|
|
112
|
+
std::vector<std::shared_ptr<AudioBus>> inputBuses_;
|
|
113
|
+
|
|
114
|
+
/// @brief Get the end time of the parameter queue.
|
|
115
|
+
/// @return The end time of the parameter queue or last endTime_ if queue is empty.
|
|
116
|
+
inline double getQueueEndTime() const noexcept {
|
|
117
|
+
if (eventsQueue_.isEmpty()) {
|
|
118
|
+
return endTime_;
|
|
119
|
+
}
|
|
120
|
+
return eventsQueue_.back().getEndTime();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/// @brief Get the end value of the parameter queue.
|
|
124
|
+
/// @return The end value of the parameter queue or last endValue_ if queue is empty.
|
|
125
|
+
inline float getQueueEndValue() const noexcept {
|
|
126
|
+
if (eventsQueue_.isEmpty()) {
|
|
127
|
+
return endValue_;
|
|
128
|
+
}
|
|
129
|
+
return eventsQueue_.back().getEndValue();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/// @brief Process all scheduled events.
|
|
133
|
+
inline void processScheduledEvents() noexcept(noexcept(eventScheduler_.processAllEvents(*this))) {
|
|
134
|
+
eventScheduler_.processAllEvents(*this);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/// @brief Update the parameter queue with a new event.
|
|
138
|
+
/// @param event The new event to add to the queue.
|
|
139
|
+
/// @note Handles connecting start value of the new event to the end value of the previous event.
|
|
140
|
+
inline void updateQueue(ParamChangeEvent &&event) {
|
|
141
|
+
eventsQueue_.pushBack(std::move(event));
|
|
142
|
+
}
|
|
143
|
+
float getValueAtTime(double time);
|
|
67
144
|
void processInputs(const std::shared_ptr<AudioBus>& outputBus, int framesToProcess, bool checkIsAlreadyProcessed);
|
|
68
145
|
void mixInputsBuses(const std::shared_ptr<AudioBus>& processingBus);
|
|
69
146
|
std::shared_ptr<AudioBus> calculateInputs(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#include <audioapi/core/AudioParamEventQueue.h>
|
|
2
|
+
|
|
3
|
+
namespace audioapi {
|
|
4
|
+
|
|
5
|
+
AudioParamEventQueue::AudioParamEventQueue() : eventQueue_() {}
|
|
6
|
+
|
|
7
|
+
void AudioParamEventQueue::pushBack(ParamChangeEvent &&event) {
|
|
8
|
+
if (eventQueue_.isEmpty()) {
|
|
9
|
+
eventQueue_.pushBack(std::move(event));
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
auto &prev = eventQueue_.peekBackMut();
|
|
13
|
+
if (prev.getType() == ParamChangeEventType::SET_TARGET) {
|
|
14
|
+
prev.setEndTime(event.getStartTime());
|
|
15
|
+
// Calculate what the SET_TARGET value would be at the new event's start
|
|
16
|
+
// time
|
|
17
|
+
prev.setEndValue(prev.getCalculateValue()(
|
|
18
|
+
prev.getStartTime(),
|
|
19
|
+
prev.getEndTime(),
|
|
20
|
+
prev.getStartValue(),
|
|
21
|
+
prev.getEndValue(),
|
|
22
|
+
event.getStartTime()));
|
|
23
|
+
}
|
|
24
|
+
event.setStartValue(prev.getEndValue());
|
|
25
|
+
eventQueue_.pushBack(std::move(event));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
bool AudioParamEventQueue::popFront(ParamChangeEvent &event) {
|
|
29
|
+
return eventQueue_.popFront(event);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
void AudioParamEventQueue::cancelScheduledValues(double cancelTime) {
|
|
33
|
+
while (!eventQueue_.isEmpty()) {
|
|
34
|
+
auto &front = eventQueue_.peekBack();
|
|
35
|
+
if (front.getEndTime() < cancelTime) {
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
if (front.getStartTime() >= cancelTime ||
|
|
39
|
+
front.getType() == ParamChangeEventType::SET_VALUE_CURVE) {
|
|
40
|
+
eventQueue_.popBack();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
void AudioParamEventQueue::cancelAndHoldAtTime(
|
|
46
|
+
double cancelTime,
|
|
47
|
+
double &endTimeCache) {
|
|
48
|
+
while (!eventQueue_.isEmpty()) {
|
|
49
|
+
auto &front = eventQueue_.peekBack();
|
|
50
|
+
if (front.getEndTime() < cancelTime || front.getStartTime() <= cancelTime) {
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
eventQueue_.popBack();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (eventQueue_.isEmpty()) {
|
|
57
|
+
endTimeCache = cancelTime;
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
auto &back = eventQueue_.peekBackMut();
|
|
62
|
+
back.setEndTime(std::min(cancelTime, back.getEndTime()));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <audioapi/core/utils/ParamChangeEvent.h>
|
|
4
|
+
#include <audioapi/core/types/ParamChangeEventType.h>
|
|
5
|
+
#include <audioapi/utils/RingBiDirectionalBuffer.hpp>
|
|
6
|
+
|
|
7
|
+
namespace audioapi {
|
|
8
|
+
|
|
9
|
+
/// @brief A queue for managing audio parameter change events.
|
|
10
|
+
/// @note The invariant of the queue is that its internal buffer always contains non-overlapping events.
|
|
11
|
+
class AudioParamEventQueue {
|
|
12
|
+
public:
|
|
13
|
+
/// @brief Constructor for AudioParamEventQueue.
|
|
14
|
+
/// @note Capacity must be valid power of two.
|
|
15
|
+
explicit AudioParamEventQueue();
|
|
16
|
+
|
|
17
|
+
/// @brief Push a new event to the back of the queue.
|
|
18
|
+
/// @note Handles connecting the start value of the new event to the end value of the last event in the queue.
|
|
19
|
+
void pushBack(ParamChangeEvent&& event);
|
|
20
|
+
|
|
21
|
+
/// @brief Pop the front event from the queue.
|
|
22
|
+
/// @return The front event in the queue.
|
|
23
|
+
bool popFront(ParamChangeEvent &event);
|
|
24
|
+
|
|
25
|
+
/// @brief Cancel scheduled parameter changes at or after the given time.
|
|
26
|
+
/// @param cancelTime The time at which to cancel scheduled changes.
|
|
27
|
+
void cancelScheduledValues(double cancelTime);
|
|
28
|
+
|
|
29
|
+
/// @brief Cancel scheduled parameter changes and hold the current value at the given time.
|
|
30
|
+
/// @param cancelTime The time at which to cancel scheduled changes.
|
|
31
|
+
void cancelAndHoldAtTime(double cancelTime, double& endTimeCache);
|
|
32
|
+
|
|
33
|
+
/// @brief Get the first event in the queue.
|
|
34
|
+
/// @return The first event in the queue.
|
|
35
|
+
inline const ParamChangeEvent& front() const noexcept {
|
|
36
|
+
return eventQueue_.peekFront();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/// @brief Get the last event in the queue.
|
|
40
|
+
/// @return The last event in the queue.
|
|
41
|
+
inline const ParamChangeEvent& back() const noexcept {
|
|
42
|
+
return eventQueue_.peekBack();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/// @brief Check if the event queue is empty.
|
|
46
|
+
/// @return True if the queue is empty, false otherwise.
|
|
47
|
+
inline bool isEmpty() const noexcept {
|
|
48
|
+
return eventQueue_.isEmpty();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/// @brief Check if the event queue is full.
|
|
52
|
+
/// @return True if the queue is full, false otherwise.
|
|
53
|
+
inline bool isFull() const noexcept {
|
|
54
|
+
return eventQueue_.isFull();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private:
|
|
58
|
+
/// @brief The queue of parameter change events.
|
|
59
|
+
/// @note INVARIANT it always holds non-overlapping events sorted by start time.
|
|
60
|
+
RingBiDirectionalBuffer<ParamChangeEvent, 32> eventQueue_;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
} // namespace audioapi
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* This file links to the FFmpeg library, which is licensed under
|
|
3
|
-
* GNU Lesser General Public License (LGPL) version 2.1 or later.
|
|
2
|
+
* This file dynamically links to the FFmpeg library, which is licensed under
|
|
3
|
+
* the GNU Lesser General Public License (LGPL) version 2.1 or later.
|
|
4
4
|
*
|
|
5
|
-
* Our own code in this file is licensed under the MIT License
|
|
6
|
-
*
|
|
7
|
-
* LGPL
|
|
5
|
+
* Our own code in this file is licensed under the MIT License and dynamic
|
|
6
|
+
* linking allows you to use this code without your entire project being subject
|
|
7
|
+
* to the terms of the LGPL. However, note that if you link statically to
|
|
8
|
+
* FFmpeg, you must comply with the terms of the LGPL for FFmpeg itself.
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
#include <audioapi/core/BaseAudioContext.h>
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* This file links to the FFmpeg library, which is licensed under the
|
|
2
|
+
* This file dynamically links to the FFmpeg library, which is licensed under the
|
|
3
3
|
* GNU Lesser General Public License (LGPL) version 2.1 or later.
|
|
4
4
|
*
|
|
5
|
-
* Our own code in this file is licensed under the MIT License
|
|
6
|
-
*
|
|
7
|
-
* LGPL
|
|
5
|
+
* Our own code in this file is licensed under the MIT License and dynamic linking
|
|
6
|
+
* allows you to use this code without your entire project being subject to the
|
|
7
|
+
* terms of the LGPL. However, note that if you link statically to FFmpeg, you must
|
|
8
|
+
* comply with the terms of the LGPL for FFmpeg itself.
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
#pragma once
|
|
@@ -7,50 +7,13 @@ ParamChangeEvent::ParamChangeEvent(
|
|
|
7
7
|
double endTime,
|
|
8
8
|
float startValue,
|
|
9
9
|
float endValue,
|
|
10
|
-
std::function<float(double, double, float, float, double)> calculateValue,
|
|
10
|
+
std::function<float(double, double, float, float, double)> &&calculateValue,
|
|
11
11
|
ParamChangeEventType type)
|
|
12
12
|
: startTime_(startTime),
|
|
13
13
|
endTime_(endTime),
|
|
14
|
+
calculateValue_(std::move(calculateValue)),
|
|
14
15
|
startValue_(startValue),
|
|
15
16
|
endValue_(endValue),
|
|
16
|
-
calculateValue_(std::move(calculateValue)),
|
|
17
17
|
type_(type) {}
|
|
18
18
|
|
|
19
|
-
double ParamChangeEvent::getEndTime() const {
|
|
20
|
-
return endTime_;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
double ParamChangeEvent::getStartTime() const {
|
|
24
|
-
return startTime_;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
float ParamChangeEvent::getEndValue() const {
|
|
28
|
-
return endValue_;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
float ParamChangeEvent::getStartValue() const {
|
|
32
|
-
return startValue_;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
std::function<float(double, double, float, float, double)>
|
|
36
|
-
ParamChangeEvent::getCalculateValue() const {
|
|
37
|
-
return calculateValue_;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
ParamChangeEventType ParamChangeEvent::getType() const {
|
|
41
|
-
return type_;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
void ParamChangeEvent::setEndTime(double endTime) {
|
|
45
|
-
endTime_ = endTime;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
void ParamChangeEvent::setStartValue(float startValue) {
|
|
49
|
-
startValue_ = startValue;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
void ParamChangeEvent::setEndValue(float endValue) {
|
|
53
|
-
endValue_ = endValue;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
19
|
} // namespace audioapi
|
|
@@ -10,32 +10,73 @@ namespace audioapi {
|
|
|
10
10
|
|
|
11
11
|
class ParamChangeEvent {
|
|
12
12
|
public:
|
|
13
|
+
ParamChangeEvent() = default;
|
|
13
14
|
explicit ParamChangeEvent(
|
|
14
15
|
double startTime,
|
|
15
16
|
double endTime,
|
|
16
17
|
float startValue,
|
|
17
18
|
float endValue,
|
|
18
|
-
std::function<float(double, double, float, float, double)> calculateValue,
|
|
19
|
+
std::function<float(double, double, float, float, double)> &&calculateValue,
|
|
19
20
|
ParamChangeEventType type);
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
[[nodiscard]] float getEndValue() const;
|
|
24
|
-
[[nodiscard]] float getStartValue() const;
|
|
25
|
-
[[nodiscard]] std::function<float(double, double, float, float, double)>
|
|
26
|
-
getCalculateValue() const;
|
|
27
|
-
[[nodiscard]] ParamChangeEventType getType() const;
|
|
22
|
+
ParamChangeEvent(const ParamChangeEvent &other) = delete;
|
|
23
|
+
ParamChangeEvent& operator=(const ParamChangeEvent &other) = delete;
|
|
28
24
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
explicit ParamChangeEvent(ParamChangeEvent &&other) noexcept
|
|
26
|
+
: startTime_(other.startTime_),
|
|
27
|
+
endTime_(other.endTime_),
|
|
28
|
+
calculateValue_(std::move(other.calculateValue_)),
|
|
29
|
+
startValue_(other.startValue_),
|
|
30
|
+
endValue_(other.endValue_),
|
|
31
|
+
type_(other.type_) {}
|
|
32
|
+
ParamChangeEvent& operator=(ParamChangeEvent &&other) noexcept {
|
|
33
|
+
if (this != &other) {
|
|
34
|
+
startTime_ = other.startTime_;
|
|
35
|
+
endTime_ = other.endTime_;
|
|
36
|
+
calculateValue_ = std::move(other.calculateValue_);
|
|
37
|
+
startValue_ = other.startValue_;
|
|
38
|
+
endValue_ = other.endValue_;
|
|
39
|
+
type_ = other.type_;
|
|
40
|
+
}
|
|
41
|
+
return *this;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
[[nodiscard]] inline double getEndTime() const noexcept {
|
|
45
|
+
return endTime_;
|
|
46
|
+
}
|
|
47
|
+
[[nodiscard]] inline double getStartTime() const noexcept {
|
|
48
|
+
return startTime_;
|
|
49
|
+
}
|
|
50
|
+
[[nodiscard]] inline float getEndValue() const noexcept {
|
|
51
|
+
return endValue_;
|
|
52
|
+
}
|
|
53
|
+
[[nodiscard]] inline float getStartValue() const noexcept {
|
|
54
|
+
return startValue_;
|
|
55
|
+
}
|
|
56
|
+
[[nodiscard]] inline const std::function<float(double, double, float, float, double)>&
|
|
57
|
+
getCalculateValue() const noexcept {
|
|
58
|
+
return calculateValue_;
|
|
59
|
+
}
|
|
60
|
+
[[nodiscard]] inline ParamChangeEventType getType() const noexcept {
|
|
61
|
+
return type_;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
inline void setEndTime(double endTime) noexcept {
|
|
65
|
+
endTime_ = endTime;
|
|
66
|
+
}
|
|
67
|
+
inline void setStartValue(float startValue) noexcept {
|
|
68
|
+
startValue_ = startValue;
|
|
69
|
+
}
|
|
70
|
+
inline void setEndValue(float endValue) noexcept {
|
|
71
|
+
endValue_ = endValue;
|
|
72
|
+
}
|
|
32
73
|
|
|
33
74
|
private:
|
|
34
75
|
double startTime_;
|
|
35
76
|
double endTime_;
|
|
77
|
+
std::function<float(double, double, float, float, double)> calculateValue_;
|
|
36
78
|
float startValue_;
|
|
37
79
|
float endValue_;
|
|
38
|
-
std::function<float(double, double, float, float, double)> calculateValue_;
|
|
39
80
|
ParamChangeEventType type_;
|
|
40
81
|
};
|
|
41
82
|
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file dynamically links to the FFmpeg library, which is licensed under the
|
|
3
|
+
* GNU Lesser General Public License (LGPL) version 2.1 or later.
|
|
4
|
+
*
|
|
5
|
+
* Our own code in this file is licensed under the MIT License and dynamic linking
|
|
6
|
+
* allows you to use this code without your entire project being subject to the
|
|
7
|
+
* terms of the LGPL. However, note that if you link statically to FFmpeg, you must
|
|
8
|
+
* comply with the terms of the LGPL for FFmpeg itself.
|
|
9
|
+
*/
|
|
10
|
+
|
|
1
11
|
#include "FFmpegDecoding.h"
|
|
2
12
|
|
|
3
13
|
namespace audioapi::ffmpegdecoding {
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file dynamically links to the FFmpeg library, which is licensed under the
|
|
3
|
+
* GNU Lesser General Public License (LGPL) version 2.1 or later.
|
|
4
|
+
*
|
|
5
|
+
* Our own code in this file is licensed under the MIT License and dynamic linking
|
|
6
|
+
* allows you to use this code without your entire project being subject to the
|
|
7
|
+
* terms of the LGPL. However, note that if you link statically to FFmpeg, you must
|
|
8
|
+
* comply with the terms of the LGPL for FFmpeg itself.
|
|
9
|
+
*/
|
|
10
|
+
|
|
1
11
|
#include <audioapi/utils/AudioBus.h>
|
|
2
12
|
#include <iostream>
|
|
3
13
|
#include <memory>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <audioapi/utils/SpscChannel.hpp>
|
|
4
|
+
|
|
5
|
+
#include <type_traits>
|
|
6
|
+
#include <functional>
|
|
7
|
+
|
|
8
|
+
namespace audioapi {
|
|
9
|
+
using namespace channels::spsc;
|
|
10
|
+
|
|
11
|
+
/// @brief A scheduler for cross-thread events.
|
|
12
|
+
/// @tparam T The type of data to be processed by the events.
|
|
13
|
+
////
|
|
14
|
+
/// It lets to schedule an event that should be performed on a different thread.
|
|
15
|
+
///
|
|
16
|
+
/// - T1 - JS thread
|
|
17
|
+
///
|
|
18
|
+
/// - T2 - Audio thread
|
|
19
|
+
///
|
|
20
|
+
/// Audio thread is looping every render quantum (~128 frames).
|
|
21
|
+
/// We want to modify some parameter on the resource used by audio thread.
|
|
22
|
+
/// We can schedule function on JS-Thread and process it before processing frames.
|
|
23
|
+
/// In this setup no locking happens and modifications can be seen by Audio thread.
|
|
24
|
+
/// @note it is intended to be used for two threads one which schedules events and one which processes them
|
|
25
|
+
/// @note it is not safe to be copied across two threads use std::shared_ptr if you need to share data
|
|
26
|
+
template <typename T>
|
|
27
|
+
class CrossThreadEventScheduler {
|
|
28
|
+
public:
|
|
29
|
+
explicit CrossThreadEventScheduler(size_t capacity) {
|
|
30
|
+
auto [sender, receiver] = channel<std::function<void(T&)>>(capacity);
|
|
31
|
+
eventSender_ = std::move(sender);
|
|
32
|
+
eventReceiver_ = std::move(receiver);
|
|
33
|
+
}
|
|
34
|
+
CrossThreadEventScheduler(const CrossThreadEventScheduler&) = delete;
|
|
35
|
+
CrossThreadEventScheduler& operator=(const CrossThreadEventScheduler&) = delete;
|
|
36
|
+
|
|
37
|
+
/// @brief Schedules an event to be processed on the audio thread.
|
|
38
|
+
/// @param event The event to schedule.
|
|
39
|
+
/// @return True if the event was successfully scheduled, false if the queue is full.
|
|
40
|
+
bool scheduleEvent(std::function<void(T&)> &&event) noexcept(noexcept(eventSender_.try_send(std::move(event)))) {
|
|
41
|
+
return eventSender_.try_send(std::move(event)) == ResponseStatus::SUCCESS;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/// @brief Processes all scheduled events.
|
|
45
|
+
/// @param data The data to pass to each event.
|
|
46
|
+
void processAllEvents(T& data) noexcept(noexcept(eventReceiver_.try_receive(std::declval<std::function<void(T&)>&>()))) {
|
|
47
|
+
std::function<void(T&)> event;
|
|
48
|
+
while (eventReceiver_.try_receive(event) == ResponseStatus::SUCCESS) {
|
|
49
|
+
event(data);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private:
|
|
54
|
+
Sender<std::function<void(T&)>> eventSender_;
|
|
55
|
+
Receiver<std::function<void(T&)>> eventReceiver_;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
} // namespace audioapi
|