|
MayaFlux 0.2.0
Digital-First Multimedia Processing Framework
|
Digital waveguide synthesis via uni- and bidirectional delay-line architectures. More...
#include <WaveguideNetwork.hpp>
Inheritance diagram for MayaFlux::Nodes::Network::WaveguideNetwork:
Collaboration diagram for MayaFlux::Nodes::Network::WaveguideNetwork:Classes | |
| struct | WaveguideSegment |
| 1D delay-line segment supporting both uni- and bidirectional propagation More... | |
Public Types | |
| enum class | WaveguideType : uint8_t { STRING , TUBE } |
| Physical structure being modeled. More... | |
| enum class | ExciterType : uint8_t { IMPULSE , NOISE_BURST , FILTERED_NOISE , SAMPLE , CONTINUOUS } |
| Excitation signal types for waveguide synthesis. More... | |
| enum class | MeasurementMode : uint8_t { PRESSURE , VELOCITY } |
| Whether node outputs represent pressure or velocity (for future use) Pressure: output is physical pressure at pickup (p_plus + p_minus) Velocity: output is particle velocity at pickup (p_plus - p_minus) More... | |
Public Member Functions | |
| WaveguideNetwork (WaveguideType type, double fundamental_freq, double sample_rate=48000.0) | |
| Create waveguide network with specified type and frequency. | |
| void | process_batch (unsigned int num_samples) override |
| Process the network for the given number of samples. | |
| size_t | get_node_count () const override |
| Get the number of nodes in the network. | |
| void | initialize () override |
| Called once before first process_batch() | |
| void | reset () override |
| Reset network to initial state. | |
| std::optional< double > | get_node_output (size_t index) const override |
| Get output of specific internal node (for ONE_TO_ONE mapping) | |
| std::unordered_map< std::string, std::string > | get_metadata () const override |
| Get network metadata for debugging/visualization. | |
| std::optional< std::span< const double > > | get_node_audio_buffer (size_t index) const override |
| Get output of specific internal node as audio buffer (for ONE_TO_ONE mapping) | |
| void | map_parameter (const std::string ¶m_name, const std::shared_ptr< Node > &source, MappingMode mode=MappingMode::BROADCAST) override |
| Map external node output to network parameter. | |
| void | map_parameter (const std::string ¶m_name, const std::shared_ptr< NodeNetwork > &source) override |
| Map external node network to network parameters (ONE_TO_ONE) | |
| void | unmap_parameter (const std::string ¶m_name) override |
| Remove parameter mapping. | |
| void | pluck (double position=0.5, double strength=1.0) |
| Pluck the string at a normalized position. | |
| void | strike (double position=0.5, double strength=1.0) |
| Strike the string/tube with an impulse. | |
| void | set_exciter_type (ExciterType type) |
| Set exciter type. | |
| ExciterType | get_exciter_type () const |
| Get current exciter type. | |
| void | set_exciter_duration (double seconds) |
| Set noise burst duration for exciter. | |
| void | set_exciter_filter (const std::shared_ptr< Filters::Filter > &filter) |
| Set filter for shaped noise excitation. | |
| void | set_exciter_sample (const std::vector< double > &sample) |
| Set custom excitation waveform. | |
| void | set_exciter_node (const std::shared_ptr< Node > &node) |
| Set continuous exciter node (for bowing/blowing) | |
| void | set_fundamental (double freq) |
| Set fundamental frequency. | |
| double | get_fundamental () const |
| Get current fundamental frequency. | |
| void | set_loss_factor (double loss) |
| Set per-sample energy loss factor. | |
| double | get_loss_factor () const |
| Get current loss factor. | |
| void | set_loop_filter (const std::shared_ptr< Filters::Filter > &filter) |
| Replace the loop filter. | |
| void | set_pickup_position (double position) |
| Set pickup position along the string. | |
| double | get_pickup_position () const |
| Get current pickup position. | |
| WaveguideType | get_type () const |
| Get waveguide type. | |
| const std::vector< WaveguideSegment > & | get_segments () const |
| Get read-only access to segments. | |
| void | set_loop_filter_closed (const std::shared_ptr< Filters::Filter > &filter) |
| Set filter for the closed-end termination (mouthpiece/nut) | |
| void | set_loop_filter_open (const std::shared_ptr< Filters::Filter > &filter) |
| Set filter for the open-end termination (bell/bridge) | |
| void | set_measurement_mode (MeasurementMode mode) |
| Set measurement mode for output. | |
| MeasurementMode | get_measurement_mode () const |
| Get current measurement mode. | |
Public Member Functions inherited from MayaFlux::Nodes::Network::NodeNetwork | |
| virtual | ~NodeNetwork ()=default |
| virtual std::optional< std::vector< double > > | get_audio_buffer () const |
| Get cached audio buffer from last process_batch() | |
| void | set_output_mode (OutputMode mode) |
| Set the network's output routing mode. | |
| OutputMode | get_output_mode () const |
| Get the current output routing mode. | |
| virtual void | set_topology (Topology topology) |
| Set the network's topology. | |
| Topology | get_topology () const |
| Get the current topology. | |
| void | set_enabled (bool enabled) |
| Enable/disable the network. | |
| bool | is_enabled () const |
| Check if network is enabled. | |
| void | set_output_scale (double scale) |
| Set the scalar multiplier applied to the network's output buffer after processing. | |
| double | get_output_scale () const |
| Get the current output scale factor. | |
| void | add_channel_usage (uint32_t channel_id) |
| Register network usage on a specific channel. | |
| void | remove_channel_usage (uint32_t channel_id) |
| Unregister network from a specific channel. | |
| bool | is_registered_on_channel (uint32_t channel_id) const |
| Check if network is registered on a channel. | |
| std::vector< uint32_t > | get_registered_channels () const |
| Get all channels this network is registered on. | |
| uint32_t | get_channel_mask () const |
| Get channel mask (bitfield of registered channels) | |
| void | set_channel_mask (uint32_t mask) |
| Set channel mask directly. | |
| bool | is_processed_this_cycle () const |
| Check if network has been processed this cycle (lock-free) | |
| void | mark_processing (bool processing) |
| Mark network as processing or not (lock-free) | |
| void | mark_processed (bool processed) |
| Mark network as processed this cycle (lock-free) | |
| bool | is_processing () const |
| Check if network is currently processing (lock-free) | |
| void | request_reset_from_channel (uint32_t channel_id) |
| Request a reset from a specific channel. | |
| virtual NetworkOperator * | get_operator () |
| virtual const NetworkOperator * | get_operator () const |
| virtual bool | has_operator () const |
| const RoutingState & | get_routing_state () const |
| Retrieves the current routing state of the network. | |
| RoutingState & | get_routing_state () |
| Retrieves the current routing state of the network (non-const) | |
| bool | needs_channel_routing () const |
| Checks if the network is currently in a routing transition phase. | |
| void | set_sample_rate (uint32_t sample_rate) |
| uint32_t | get_sample_rate () const |
| void | set_block_size (uint32_t block_size) |
| uint32_t | get_block_size () const |
Private Member Functions | |
| void | compute_delay_length () |
| void | create_default_loop_filter () |
| double | read_with_interpolation (const Memory::HistoryBuffer< double > &delay, size_t integer_part, double fraction) const |
| Read from delay line with linear fractional interpolation. | |
| double | generate_exciter_sample () |
| void | initialize_exciter () |
| void | update_mapped_parameters () |
| void | apply_broadcast_parameter (const std::string ¶m, double value) |
| void | apply_one_to_one_parameter (const std::string ¶m, const std::shared_ptr< NodeNetwork > &source) |
| void | process_unidirectional (WaveguideSegment &seg, unsigned int num_samples) |
| void | process_bidirectional (WaveguideSegment &seg, unsigned int num_samples) |
| double | observe_sample (const WaveguideSegment &seg) const |
Private Attributes | |
| WaveguideType | m_type |
| double | m_fundamental |
| std::vector< WaveguideSegment > | m_segments |
| size_t | m_delay_length_integer { 0 } |
| double | m_delay_length_fraction { 0.0 } |
| size_t | m_pickup_sample { 0 } |
| ExciterType | m_exciter_type { ExciterType::NOISE_BURST } |
| MeasurementMode | m_measurement_mode { MeasurementMode::PRESSURE } |
| double | m_exciter_duration { 0.005 } |
| std::vector< double > | m_exciter_sample |
| std::shared_ptr< Filters::Filter > | m_exciter_filter |
| std::shared_ptr< Node > | m_exciter_node |
| size_t | m_exciter_sample_position {} |
| bool | m_exciter_active {} |
| size_t | m_exciter_samples_remaining {} |
| double | m_last_output {} |
| Kinesis::Stochastic::Stochastic | m_random_generator |
Additional Inherited Members | |
Protected Member Functions inherited from MayaFlux::Nodes::Network::NodeNetwork | |
| void | ensure_initialized () |
| Ensure initialize() is called exactly once. | |
| void | apply_output_scale () |
| Apply m_output_scale to m_last_audio_buffer. | |
Static Protected Member Functions inherited from MayaFlux::Nodes::Network::NodeNetwork | |
| static std::unordered_map< size_t, std::vector< size_t > > | build_grid_2d_neighbors (size_t width, size_t height) |
| Build neighbor map for GRID_2D topology. | |
| static std::unordered_map< size_t, std::vector< size_t > > | build_grid_3d_neighbors (size_t width, size_t height, size_t depth) |
| Build neighbor map for GRID_3D topology. | |
| static std::unordered_map< size_t, std::vector< size_t > > | build_ring_neighbors (size_t count) |
| Build neighbor map for RING topology. | |
| static std::unordered_map< size_t, std::vector< size_t > > | build_chain_neighbors (size_t count) |
| Build neighbor map for CHAIN topology. | |
Protected Attributes inherited from MayaFlux::Nodes::Network::NodeNetwork | |
| Topology | m_topology = Topology::INDEPENDENT |
| OutputMode | m_output_mode = OutputMode::NONE |
| bool | m_enabled = true |
| bool | m_initialized = false |
| uint32_t | m_sample_rate { 48000 } |
| uint32_t | m_block_size { 512 } |
| std::vector< ParameterMapping > | m_parameter_mappings |
| std::atomic< uint32_t > | m_channel_mask { 0 } |
| Bitfield of channels this network is registered on. | |
| std::atomic< uint32_t > | m_pending_reset_mask { 0 } |
| std::atomic< bool > | m_processing_state { false } |
| Per-channel processing state (lock-free atomic flags) | |
| std::atomic< bool > | m_processed_this_cycle { false } |
| std::vector< double > | m_last_audio_buffer |
| double | m_output_scale { 1.0 } |
| Post-processing scalar applied to m_last_audio_buffer each batch. | |
Digital waveguide synthesis via uni- and bidirectional delay-line architectures.
Digital waveguide synthesis models vibrating structures as traveling waves propagating through delay lines. A loop filter at each termination simulates frequency-dependent energy loss. This complements ModalNetwork (frequency-domain) with time-domain physical modeling: where ModalNetwork decomposes resonance into independent modes, WaveguideNetwork simulates wave propagation directly.
WaveguideSegment is direction-agnostic and supports both modes via PropagationMode:
UNIDIRECTIONAL (STRING): Single loop. Wave circulates on p_plus only. Karplus-Strong extended model. Loop filter at the single termination controls frequency-dependent damping.
exciter ──► p_plus ──► [delay N] ──► loop_filter ──► loss ──┐ output ◄── tap(pickup_sample) │ └─────────────────────────────────────────────────┘
BIDIRECTIONAL (TUBE): Two rails. p_plus travels toward the open end, p_minus returns toward the closed end. Reflection sign at each termination determines harmonic series:
Open end (bell): pressure antinode, sign inverted → adds even harmonics Output is the physical pressure sum p_plus[pickup] + p_minus[pickup].
exciter ──► p_plus ──► [delay N] ──► loop_filter ──► loss ──► open-end (−) output ◄── tap │ p_minus ◄── [delay N] ◄── loop_filter ◄── loss ◄── closed-end (+)
pluck() seeds p_plus with a triangle waveform (shaped initial displacement). strike() seeds p_plus with a Gaussian-windowed noise burst at the strike point. Both clear p_minus, ensuring a clean bidirectional state on re-excitation. Continuous and sample-based exciters inject per-sample into p_plus at the closed end on every call to process_batch().
Definition at line 85 of file WaveguideNetwork.hpp.