Skip to content

Commit

Permalink
Fix EffectNode API
Browse files Browse the repository at this point in the history
  • Loading branch information
SirBob01 committed May 17, 2023
1 parent 7db2793 commit 056a2d5
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 127 deletions.
6 changes: 3 additions & 3 deletions src/Sound/Chunk.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include "../Types.hpp"
#include "./EffectGraph.hpp"
#include "./EffectNode.hpp"
#include "./Sound.hpp"

namespace Dynamo::Sound {
Expand Down Expand Up @@ -30,10 +30,10 @@ namespace Dynamo::Sound {
std::reference_wrapper<Sound> sound;

/**
* @brief Reference to the audio processing effects graph.
* @brief Reference to the audio processing effect graph.
*
*/
std::reference_wrapper<EffectGraph> effects;
std::reference_wrapper<EffectNode> effect;

/**
* @brief Frame offset of the chunk.
Expand Down
20 changes: 0 additions & 20 deletions src/Sound/EffectGraph.cpp

This file was deleted.

31 changes: 0 additions & 31 deletions src/Sound/EffectGraph.hpp

This file was deleted.

17 changes: 16 additions & 1 deletion src/Sound/EffectNode.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#include "./EffectNode.hpp"

namespace Dynamo::Sound {
b8 EffectNode::has_cycles() {
// TODO: Implement
}

const std::vector<EffectConnection> &EffectNode::get_outgoing() const {
return _outgoing;
}
Expand All @@ -9,6 +13,9 @@ namespace Dynamo::Sound {
u32 input_channel,
u32 output_channel) {
_outgoing.push_back({destination, input_channel, output_channel});
if (has_cycles()) {
Log::error("Jukebox EffectNode graph disallows cycles.");
}
}

void EffectNode::disconnect() { _outgoing.clear(); }
Expand All @@ -28,6 +35,14 @@ namespace Dynamo::Sound {
it++;
}
}
Log::error("EffectNode - Invalid disconnection.");
Log::error("Jukebox EffectNode graph attempted to disconnect a "
"non-existent node.");
}

Sound &EffectNode::run(Sound &src,
u32 offset,
u32 length,
ListenerSet &listeners) {
// TODO: Implement
}
} // namespace Dynamo::Sound
27 changes: 22 additions & 5 deletions src/Sound/EffectNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ namespace Dynamo::Sound {
class EffectNode {
std::vector<EffectConnection> _outgoing;

private:
/**
* @brief Test if the graph has cycles.
*
* @return b8
*/
b8 has_cycles();

public:
/**
* @brief Destroy the EffectNode object.
Expand Down Expand Up @@ -88,15 +96,24 @@ namespace Dynamo::Sound {
u32 output_channel = 0);

/**
* @brief Process a waveform channel and produce the output sound, which
* may contain multiple channels.
* @brief Run the Sound through the graph rooted at this node.
*
* @param src
* @param offset
* @param length
* @param listeners
* @return Sound&
*/
Sound &run(Sound &src, u32 offset, u32 length, ListenerSet &listeners);

/**
* @brief Process a Sound.
*
* @param src
* @param length
* @param listeners
*/
virtual Sound &process_channel(WaveSample *src,
u32 length,
ListenerSet &listeners) = 0;
virtual Sound &
process(Sound &src, u32 offset, u32 length, ListenerSet &listeners) = 0;
};
} // namespace Dynamo::Sound
14 changes: 9 additions & 5 deletions src/Sound/Filters/AttenuationEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@ namespace Dynamo::Sound {
return (_cutoff_radius - distance) / (_cutoff_radius - _inner_radius);
}

Sound &AttenuationEffect::process_channel(WaveSample *src,
u32 length,
ListenerSet &listeners) {
Sound &AttenuationEffect::process(Sound &src,
u32 offset,
u32 length,
ListenerSet &listeners) {
ListenerProperties &listener = listeners.find_closest(_position);
f32 distance = (_position - listener.position).length();
f32 gain = linear(distance);

for (u32 f = 0; f < length; f++) {
_output[0][f] = src[f] * gain;
_output.resize(length, src.channels());
for (u32 c = 0; c < _output.channels(); c++) {
for (u32 f = 0; f < _output.frames(); f++) {
_output[c][f] = src[c][f + offset] * gain;
}
}
return _output;
}
Expand Down
7 changes: 4 additions & 3 deletions src/Sound/Filters/AttenuationEffect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ namespace Dynamo::Sound {

inline void set_position(Vec3 position) { _position = position; }

Sound &process_channel(WaveSample *src,
u32 length,
ListenerSet &listeners) override;
Sound &process(Sound &src,
u32 offset,
u32 length,
ListenerSet &listeners) override;
};
} // namespace Dynamo::Sound
11 changes: 6 additions & 5 deletions src/Sound/Filters/BinauralEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@ namespace Dynamo::Sound {
_output.set_channels(2);
}

Sound &BinauralEffect::process_channel(WaveSample *src,
u32 length,
ListenerSet &listeners) {
Sound &BinauralEffect::process(Sound &src,
u32 offset,
u32 length,
ListenerSet &listeners) {
ListenerProperties &listener = listeners.find_closest(_position);
_output.set_frames(length);
_hrtf.get().calculate_HRIR(listener.position,
listener.rotation,
_position,
_impulse_response);
_output.set_frames(length);
for (i32 c = 0; c < 2; c++) {
_convolvers[c].initialize(_impulse_response[c],
_impulse_response.frames());
_convolvers[c].compute(src, _output[c], length);
_convolvers[c].compute(src[c] + offset, _output[c], length);
}
return _output;
}
Expand Down
7 changes: 4 additions & 3 deletions src/Sound/Filters/BinauralEffect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ namespace Dynamo::Sound {
*/
inline void set_position(Vec3 position) { _position = position; }

Sound &process_channel(WaveSample *src,
u32 length,
ListenerSet &listeners) override;
Sound &process(Sound &src,
u32 offset,
u32 length,
ListenerSet &listeners) override;
};
} // namespace Dynamo::Sound
41 changes: 5 additions & 36 deletions src/Sound/Filters/StereoEffect.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#include "./StereoEffect.hpp"

namespace Dynamo::Sound {
Sound &StereoEffect::process_channel(WaveSample *src,
u32 length,
ListenerSet &listeners) {
Sound &StereoEffect::process(Sound &src,
u32 offset,
u32 length,
ListenerSet &listeners) {
ListenerProperties &listener = listeners.find_closest(_position);
Vec3 delta = _position - listener.position;
Vec3 up = listener.rotation.up();
Expand All @@ -26,41 +27,9 @@ namespace Dynamo::Sound {
for (u32 c = 0; c < 2; c++) {
f32 gain = c == 0 ? l_gain : r_gain;
for (u32 f = 0; f < length; f++) {
_output[c][f] = src[f] * gain;
_output[c][f] = src[c][f + offset] * gain;
}
}
return _output;
}

// Sound &Stereo::apply(Sound &src,
// const u32 src_offset,
// const u32 length,
// const DynamicMaterial &material,
// const ListenerProperties &listener) {
// Vec3 delta = material.position - listener.position;
// Vec3 up = listener.rotation.up();
// Vec3 right = listener.rotation.right();
// Vec3 displacement = (delta - up * (delta * up));
// f32 distance = displacement.length();

// // Assume that if the distance is 0, the sound is centered
// f32 pan = 0.5;
// if (distance > 0) {
// Vec3 direction = displacement / distance;
// pan = ((direction * right) + 1) * 0.5;
// }

// // Square-law panning
// f32 l_gain = std::sqrt(1 - pan);
// f32 r_gain = std::sqrt(pan);

// _output.set_frames(length);
// for (u32 c = 0; c < 2; c++) {
// f32 gain = c == 0 ? l_gain : r_gain;
// for (u32 f = 0; f < length; f++) {
// _output[c][f] = src[c][f + src_offset] * gain;
// }
// }
// return _output;
// }
} // namespace Dynamo::Sound
7 changes: 4 additions & 3 deletions src/Sound/Filters/StereoEffect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ namespace Dynamo::Sound {
*/
inline void set_position(Vec3 position) { _position = position; }

Sound &process_channel(WaveSample *src,
u32 length,
ListenerSet &listeners) override;
Sound &process(Sound &src,
u32 offset,
u32 length,
ListenerSet &listeners) override;
};
} // namespace Dynamo::Sound
17 changes: 8 additions & 9 deletions src/Sound/Jukebox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ namespace Dynamo::Sound {
}

void Jukebox::process_chunk(Chunk &chunk) {
Sound &sound = chunk.sound.get();
EffectGraph &effects = chunk.effects.get();
Sound &sound = chunk.sound;
EffectNode &effect = chunk.effect;

// Calculate the number of frames in the destination
f64 frame_stop = std::min(chunk.frame + MAX_CHUNK_LENGTH,
Expand All @@ -117,10 +117,8 @@ namespace Dynamo::Sound {
}

// Apply the effects graph
transformed = effects.process_sound(transformed,
0,
transformed.frames(),
_listeners);
transformed =
effect.process(transformed, 0, transformed.frames(), _listeners);

// Mix the filtered sound onto the composite signal
for (u32 f = 0; f < transformed.frames(); f++) {
Expand Down Expand Up @@ -285,9 +283,9 @@ namespace Dynamo::Sound {

HRTF &Jukebox::get_hrtf() { return _hrtf; }

void Jukebox::play(Sound &sound, EffectGraph &effects, f64 start_seconds) {
void Jukebox::play(Sound &sound, EffectNode &effect, f64 start_seconds) {
f32 frame = _output_state.sample_rate * start_seconds;
_chunks.push_back({sound, effects, frame});
_chunks.push_back({sound, effect, frame});
}

void Jukebox::update() {
Expand All @@ -304,7 +302,8 @@ namespace Dynamo::Sound {
auto s_it = _chunks.begin();
while (s_it != _chunks.end()) {
Chunk &chunk = *s_it;
if (chunk.frame >= chunk.sound.get().frames()) {
Sound &sound = chunk.sound;
if (chunk.frame >= sound.frames()) {
s_it = _chunks.erase(s_it);
} else {
process_chunk(chunk);
Expand Down
6 changes: 3 additions & 3 deletions src/Sound/Jukebox.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

#include "./Chunk.hpp"
#include "./Device.hpp"
#include "./EffectGraph.hpp"
#include "./EffectNode.hpp"
#include "./HRTF.hpp"
#include "./Listener.hpp"
#include "./Resample.hpp"
Expand Down Expand Up @@ -249,10 +249,10 @@ namespace Dynamo::Sound {
* @brief Play a static sound
*
* @param sound Sound source
* @param effects Effects processing graph
* @param effect Effect processing graph
* @param start_seconds Start time offset in seconds
*/
void play(Sound &sound, EffectGraph &effects, f64 start_seconds = 0.0);
void play(Sound &sound, EffectNode &effect, f64 start_seconds = 0.0);

/**
* @brief Update Jukebox's internal state and process all chunks
Expand Down

0 comments on commit 056a2d5

Please sign in to comment.