From 3947725f0408c4d2b400785ae1c74004738cad51 Mon Sep 17 00:00:00 2001 From: David Reid Date: Tue, 18 Jan 2022 18:31:18 +1000 Subject: [PATCH] Add support for using ma_node_graph as a node. This allows the node graph to be connected to another node graph. --- miniaudio.h | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/miniaudio.h b/miniaudio.h index c650db75..05e8b9e1 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -10364,6 +10364,7 @@ MA_API ma_node_graph_config ma_node_graph_config_init(ma_uint32 channels); struct ma_node_graph { /* Immutable. */ + ma_node_base base; /* The node graph itself is a node so it can be connected as an input to different node graph. This has zero inputs and calls ma_node_graph_read_pcm_frames() to generate it's output. */ ma_node_base endpoint; /* Special node that all nodes eventually connect to. Data is read from this node in ma_node_graph_read_pcm_frames(). */ ma_uint16 nodeCacheCapInFrames; @@ -67733,6 +67734,28 @@ static ma_bool32 ma_node_graph_is_reading(ma_node_graph* pNodeGraph) #endif +static void ma_node_graph_node_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut) +{ + ma_node_graph* pNodeGraph = (ma_node_graph*)pNode; + ma_uint64 framesRead; + + ma_node_graph_read_pcm_frames(pNodeGraph, ppFramesOut[0], *pFrameCountOut, &framesRead); + + *pFrameCountOut = (ma_uint32)framesRead; /* Safe cast. */ + + (void)ppFramesIn; + (void)pFrameCountIn; +} + +static ma_node_vtable g_node_graph_node_vtable = +{ + ma_node_graph_node_process_pcm_frames, + NULL, /* onGetRequiredInputFrameCount */ + 0, /* 1 input buses. */ + 1, /* 1 output bus. */ + 0 /* Flags. */ +}; + static void ma_node_graph_endpoint_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut) { MA_ASSERT(pNode != NULL); @@ -67769,7 +67792,9 @@ static ma_node_vtable g_node_graph_endpoint_vtable = MA_API ma_result ma_node_graph_init(const ma_node_graph_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_node_graph* pNodeGraph) { ma_result result; + ma_node_config baseConfig; ma_node_config endpointConfig; + ma_uint32 baseInputChannels = 0; if (pNodeGraph == NULL) { return MA_INVALID_ARGS; @@ -67781,6 +67806,20 @@ MA_API ma_result ma_node_graph_init(const ma_node_graph_config* pConfig, const m pNodeGraph->nodeCacheCapInFrames = MA_DEFAULT_NODE_CACHE_CAP_IN_FRAMES_PER_BUS; } + + /* Base node so we can use the node graph as a node into another graph. */ + baseConfig = ma_node_config_init(); + baseConfig.vtable = &g_node_graph_node_vtable; + baseConfig.pInputChannels = &baseInputChannels; /* <-- Always zero. */ + baseConfig.pOutputChannels = &pConfig->channels; + + result = ma_node_init(pNodeGraph, &baseConfig, pAllocationCallbacks, &pNodeGraph->base); + if (result != MA_SUCCESS) { + return result; + } + + + /* Endpoint. */ endpointConfig = ma_node_config_init(); endpointConfig.vtable = &g_node_graph_endpoint_vtable; endpointConfig.pInputChannels = &pConfig->channels; @@ -67788,6 +67827,7 @@ MA_API ma_result ma_node_graph_init(const ma_node_graph_config* pConfig, const m result = ma_node_init(pNodeGraph, &endpointConfig, pAllocationCallbacks, &pNodeGraph->endpoint); if (result != MA_SUCCESS) { + ma_node_uninit(&pNodeGraph->base, pAllocationCallbacks); return result; }