App-MHFS

 view release on metacpan or  search on metacpan

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN


    ```c
    ma_sound_init_from_file(&engine, "my_sound.wav", MA_SOUND_FLAG_STREAM, pGroup, NULL, &sound);
    ```

When streaming sounds, 2 seconds worth of audio data is stored in memory. Although it should work
fine, it's inefficient to use streaming for short sounds. Streaming is useful for things like music
tracks in games.

When you initialize a sound, if you specify a sound group the sound will be attached to that group
automatically. If you set it to NULL, it will be automatically attached to the engine's endpoint.
If you would instead rather leave the sound unattached by default, you can can specify the
`MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT` flag. This is useful if you want to set up a complex node
graph.

Sounds are not started by default. To start a sound, use `ma_sound_start()`. Stop a sound with
`ma_sound_stop()`.

Sounds can have their volume controlled with `ma_sound_set_volume()` in the same way as the
engine's master volume.

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN




7. Node Graph
=============
miniaudio's routing infrastructure follows a node graph paradigm. The idea is that you create a
node whose outputs are attached to inputs of another node, thereby creating a graph. There are
different types of nodes, with each node in the graph processing input data to produce output,
which is then fed through the chain. Each node in the graph can apply their own custom effects. At
the start of the graph will usually be one or more data source nodes which have no inputs, but
instead pull their data from a data source. At the end of the graph is an endpoint which represents
the end of the chain and is where the final output is ultimately extracted from.

Each node has a number of input buses and a number of output buses. An output bus from a node is
attached to an input bus of another. Multiple nodes can connect their output buses to another
node's input bus, in which case their outputs will be mixed before processing by the node. Below is
a diagram that illustrates a hypothetical node graph setup:

    ```
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Data flows left to right >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

                         +----= Splitter |                                +----= ENDPOINT |
    +---------------+    |    |          =----+    +-----------------+    |    +----------+
    | Data Source 2 =----+    +----------+    +----=  Echo / Delay   =----+
    +---------------+                              +-----------------+
    ```

In the above graph, it starts with two data sources whose outputs are attached to the input of a
splitter node. It's at this point that the two data sources are mixed. After mixing, the splitter
performs it's processing routine and produces two outputs which is simply a duplication of the
input stream. One output is attached to a low pass filter, whereas the other output is attached to
a echo/delay. The outputs of the the low pass filter and the echo are attached to the endpoint, and
since they're both connected to the same input but, they'll be mixed.

Each input bus must be configured to accept the same number of channels, but the number of channels
used by input buses can be different to the number of channels for output buses in which case
miniaudio will automatically convert the input data to the output channel count before processing.
The number of channels of an output bus of one node must match the channel count of the input bus
it's attached to. The channel counts cannot be changed after the node has been initialized. If you
attempt to attach an output bus to an input bus with a different channel count, attachment will
fail.

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN


    ```c
    ma_node_graph_config nodeGraphConfig = ma_node_graph_config_init(myChannelCount);

    result = ma_node_graph_init(&nodeGraphConfig, NULL, &nodeGraph);    // Second parameter is a pointer to allocation callbacks.
    if (result != MA_SUCCESS) {
        // Failed to initialize node graph.
    }
    ```

When you initialize the node graph, you're specifying the channel count of the endpoint. The
endpoint is a special node which has one input bus and one output bus, both of which have the
same channel count, which is specified in the config. Any nodes that connect directly to the
endpoint must be configured such that their output buses have the same channel count. When you read
audio data from the node graph, it'll have the channel count you specified in the config. To read
data from the graph:

    ```c
    ma_uint32 framesRead;
    result = ma_node_graph_read_pcm_frames(&nodeGraph, pFramesOut, frameCount, &framesRead);
    if (result != MA_SUCCESS) {
        // Failed to read data from the node graph.
    }
    ```

When you read audio data, miniaudio starts at the node graph's endpoint node which then pulls in
data from it's input attachments, which in turn recusively pull in data from their inputs, and so
on. At the start of the graph there will be some kind of data source node which will have zero
inputs and will instead read directly from a data source. The base nodes don't literally need to
read from a `ma_data_source` object, but they will always have some kind of underlying object that
sources some kind of audio. The `ma_data_source_node` node can be used to read from a
`ma_data_source`. Data is always in floating-point format and in the number of channels you
specified when the graph was initialized. The sample rate is defined by the underlying data sources.
It's up to you to ensure they use a consistent and appropraite sample rate.

The `ma_node` API is designed to allow custom nodes to be implemented with relative ease, but

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    ```

The data source node will use the output channel count to determine the channel count of the output
bus. There will be 1 output bus and 0 input buses (data will be drawn directly from the data
source). The data source must output to floating-point (`ma_format_f32`) or else an error will be
returned from `ma_data_source_node_init()`.

By default the node will not be attached to the graph. To do so, use `ma_node_attach_output_bus()`:

    ```c
    result = ma_node_attach_output_bus(&dataSourceNode, 0, ma_node_graph_get_endpoint(&nodeGraph), 0);
    if (result != MA_SUCCESS) {
        // Failed to attach node.
    }
    ```

The code above connects the data source node directly to the endpoint. Since the data source node
has only a single output bus, the index will always be 0. Likewise, the endpoint only has a single
input bus which means the input bus index will also always be 0.

To detach a specific output bus, use `ma_node_detach_output_bus()`. To detach all output buses, use
`ma_node_detach_all_output_buses()`. If you want to just move the output bus from one attachment to
another, you do not need to detach first. You can just call `ma_node_attach_output_bus()` and it'll
deal with it for you.

Less frequently you may want to create a specialized node. This will be a node where you implement
your own processing callback to apply a custom effect of some kind. This is similar to initalizing
one of the stock node types, only this time you need to specify a pointer to a vtable containing a

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN


Custom nodes can be assigned some flags to describe their behaviour. These are set via the vtable
and include the following:

    +-----------------------------------------+---------------------------------------------------+
    | Flag Name                               | Description                                       |
    +-----------------------------------------+---------------------------------------------------+
    | MA_NODE_FLAG_PASSTHROUGH                | Useful for nodes that do not do any kind of audio |
    |                                         | processing, but are instead used for tracking     |
    |                                         | time, handling events, etc. Also used by the      |
    |                                         | internal endpoint node. It reads directly from    |
    |                                         | the input bus to the output bus. Nodes with this  |
    |                                         | flag must have exactly 1 input bus and 1 output   |
    |                                         | bus, and both buses must have the same channel    |
    |                                         | counts.                                           |
    +-----------------------------------------+---------------------------------------------------+
    | MA_NODE_FLAG_CONTINUOUS_PROCESSING      | Causes the processing callback to be called even  |
    |                                         | when no data is available to be read from input   |
    |                                         | attachments. This is useful for effects like      |
    |                                         | echos where there will be a tail of audio data    |
    |                                         | that still needs to be processed even when the    |

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    ```c
    ma_splitter_node_config splitterNodeConfig = ma_splitter_node_config_init(channelsIn, channelsOut);

    ma_splitter_node splitterNode;
    result = ma_splitter_node_init(&nodeGraph, &splitterNodeConfig, NULL, &splitterNode);
    if (result != MA_SUCCESS) {
        // Failed to create node.
    }

    // Attach your output buses to two different input buses (can be on two different nodes).
    ma_node_attach_output_bus(&splitterNode, 0, ma_node_graph_get_endpoint(&nodeGraph), 0); // Attach directly to the endpoint.
    ma_node_attach_output_bus(&splitterNode, 1, &myEffectNode,                          0); // Attach to input bus 0 of some effect node.
    ```

The volume of an output bus can be configured on a per-bus basis:

    ```c
    ma_node_set_output_bus_volume(&splitterNode, 0, 0.5f);
    ma_node_set_output_bus_volume(&splitterNode, 1, 0.5f);
    ```

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

nodes, followed by each of the attachments to each of it's input nodes, and then do any final clean
up.

With the above design, the worst-case scenario is `ma_node_detach_output_bus()` taking as long as
it takes to process the output bus being detached. This will happen if it's called at just the
wrong moment where the audio thread has just iterated it and has just started processing. The
caller of `ma_node_detach_output_bus()` will stall until the audio thread is finished, which
includes the cost of recursively processing it's inputs. This is the biggest compromise made with
the approach taken by miniaudio for it's lock-free processing system. The cost of detaching nodes
earlier in the pipeline (data sources, for example) will be cheaper than the cost of detaching
higher level nodes, such as some kind of final post-processing endpoint. If you need to do mass
detachments, detach starting from the lowest level nodes and work your way towards the final
endpoint node (but don't try detaching the node graph's endpoint). If the audio thread is not
running, detachment will be fast and detachment in any order will be the same. The reason nodes
need to wait for their input attachments to complete is due to the potential for desyncs between
data sources. If the node was to terminate processing mid way through processing it's inputs,
there's a chance that some of the underlying data sources will have been read, but then others not.
That will then result in a potential desynchronization when detaching and reattaching higher-level
nodes. A possible solution to this is to have an option when detaching to terminate processing
before processing all input attachments which should be fairly simple.

Another compromise, albeit less significant, is locking when attaching and detaching nodes. This
locking is achieved by means of a spinlock in order to reduce memory overhead. A lock is present

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    ma_uint16 nodeCacheCapInFrames;
} ma_node_graph_config;

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;

    /* Read and written by multiple threads. */
    MA_ATOMIC(4, ma_bool32) isReading;
};

MA_API ma_result ma_node_graph_init(const ma_node_graph_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_node_graph* pNodeGraph);
MA_API void ma_node_graph_uninit(ma_node_graph* pNodeGraph, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_node* ma_node_graph_get_endpoint(ma_node_graph* pNodeGraph);
MA_API ma_result ma_node_graph_read_pcm_frames(ma_node_graph* pNodeGraph, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_uint32 ma_node_graph_get_channels(const ma_node_graph* pNodeGraph);
MA_API ma_uint64 ma_node_graph_get_time(const ma_node_graph* pNodeGraph);
MA_API ma_result ma_node_graph_set_time(ma_node_graph* pNodeGraph, ma_uint64 globalTime);



/* Data source node. 0 input buses, 1 output bus. Used for reading from a data source. */
typedef struct
{

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

typedef struct ma_sound  ma_sound;


/* Sound flags. */
typedef enum
{
    MA_SOUND_FLAG_STREAM                = 0x00000001,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM */
    MA_SOUND_FLAG_DECODE                = 0x00000002,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE */
    MA_SOUND_FLAG_ASYNC                 = 0x00000004,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC */
    MA_SOUND_FLAG_WAIT_INIT             = 0x00000008,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT */
    MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT = 0x00000010,   /* Do not attach to the endpoint by default. Useful for when setting up nodes in a complex graph system. */
    MA_SOUND_FLAG_NO_PITCH              = 0x00000020,   /* Disable pitch shifting with ma_sound_set_pitch() and ma_sound_group_set_pitch(). This is an optimization. */
    MA_SOUND_FLAG_NO_SPATIALIZATION     = 0x00000040    /* Disable spatialization. */
} ma_sound_flags;

#ifndef MA_ENGINE_MAX_LISTENERS
#define MA_ENGINE_MAX_LISTENERS             4
#endif

#define MA_LISTENER_INDEX_CLOSEST           ((ma_uint8)-1)

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

MA_API void ma_engine_node_uninit(ma_engine_node* pEngineNode, const ma_allocation_callbacks* pAllocationCallbacks);


#define MA_SOUND_SOURCE_CHANNEL_COUNT   0xFFFFFFFF

typedef struct
{
    const char* pFilePath;                      /* Set this to load from the resource manager. */
    const wchar_t* pFilePathW;                  /* Set this to load from the resource manager. */
    ma_data_source* pDataSource;                /* Set this to load from an existing data source. */
    ma_node* pInitialAttachment;                /* If set, the sound will be attached to an input of this node. This can be set to a ma_sound. If set to NULL, the sound will be attached directly to the endpoint unless MA_SOUND_FLAG_NO_DEFAULT_ATTACHM...
    ma_uint32 initialAttachmentInputBusIndex;   /* The index of the input bus of pInitialAttachment to attach the sound to. */
    ma_uint32 channelsIn;                       /* Ignored if using a data source as input (the data source's channel count will be used always). Otherwise, setting to 0 will cause the engine's channel count to be used. */
    ma_uint32 channelsOut;                      /* Set this to 0 (default) to use the engine's channel count. Set to MA_SOUND_SOURCE_CHANNEL_COUNT to use the data source's channel count (only used if using a data source as input). */
    ma_uint32 flags;                            /* A combination of MA_SOUND_FLAG_* flags. */
    ma_uint64 initialSeekPointInPCMFrames;      /* Initializes the sound such that it's seeked to this location by default. */
    ma_uint64 rangeBegInPCMFrames;
    ma_uint64 rangeEndInPCMFrames;
    ma_uint64 loopPointBegInPCMFrames;
    ma_uint64 loopPointEndInPCMFrames;
    ma_bool32 isLooping;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN


MA_API ma_result ma_engine_init(const ma_engine_config* pConfig, ma_engine* pEngine);
MA_API void ma_engine_uninit(ma_engine* pEngine);
MA_API ma_result ma_engine_read_pcm_frames(ma_engine* pEngine, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_node_graph* ma_engine_get_node_graph(ma_engine* pEngine);
#if !defined(MA_NO_RESOURCE_MANAGER)
MA_API ma_resource_manager* ma_engine_get_resource_manager(ma_engine* pEngine);
#endif
MA_API ma_device* ma_engine_get_device(ma_engine* pEngine);
MA_API ma_log* ma_engine_get_log(ma_engine* pEngine);
MA_API ma_node* ma_engine_get_endpoint(ma_engine* pEngine);
MA_API ma_uint64 ma_engine_get_time(const ma_engine* pEngine);
MA_API ma_result ma_engine_set_time(ma_engine* pEngine, ma_uint64 globalTime);
MA_API ma_uint32 ma_engine_get_channels(const ma_engine* pEngine);
MA_API ma_uint32 ma_engine_get_sample_rate(const ma_engine* pEngine);

MA_API ma_result ma_engine_start(ma_engine* pEngine);
MA_API ma_result ma_engine_stop(ma_engine* pEngine);
MA_API ma_result ma_engine_set_volume(ma_engine* pEngine, float volume);
MA_API ma_result ma_engine_set_gain_db(ma_engine* pEngine, float gainDB);

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN


static ma_node_vtable g_node_graph_node_vtable =
{
    ma_node_graph_node_process_pcm_frames,
    NULL,   /* onGetRequiredInputFrameCount */
    0,      /* 0 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);
    MA_ASSERT(ma_node_get_input_bus_count(pNode)  == 1);
    MA_ASSERT(ma_node_get_output_bus_count(pNode) == 1);

    /* Input channel count needs to be the same as the output channel count. */
    MA_ASSERT(ma_node_get_input_channels(pNode, 0) == ma_node_get_output_channels(pNode, 0));

    /* We don't need to do anything here because it's a passthrough. */
    (void)pNode;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    (void)pFrameCountOut;

#if 0
    /* The data has already been mixed. We just need to move it to the output buffer. */
    if (ppFramesIn != NULL) {
        ma_copy_pcm_frames(ppFramesOut[0], ppFramesIn[0], *pFrameCountOut, ma_format_f32, ma_node_get_output_channels(pNode, 0));
    }
#endif
}

static ma_node_vtable g_node_graph_endpoint_vtable =
{
    ma_node_graph_endpoint_process_pcm_frames,
    NULL,   /* onGetRequiredInputFrameCount */
    1,      /* 1 input bus. */
    1,      /* 1 output bus. */
    MA_NODE_FLAG_PASSTHROUGH    /* Flags. The endpoint is a passthrough. */
};

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;

    if (pNodeGraph == NULL) {
        return MA_INVALID_ARGS;
    }

    MA_ZERO_OBJECT(pNodeGraph);
    pNodeGraph->nodeCacheCapInFrames = pConfig->nodeCacheCapInFrames;
    if (pNodeGraph->nodeCacheCapInFrames == 0) {
        pNodeGraph->nodeCacheCapInFrames = MA_DEFAULT_NODE_CACHE_CAP_IN_FRAMES_PER_BUS;
    }

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

    baseConfig.vtable = &g_node_graph_node_vtable;
    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;
    endpointConfig.pOutputChannels = &pConfig->channels;

    result = ma_node_init(pNodeGraph, &endpointConfig, pAllocationCallbacks, &pNodeGraph->endpoint);
    if (result != MA_SUCCESS) {
        ma_node_uninit(&pNodeGraph->base, pAllocationCallbacks);
        return result;
    }

    return MA_SUCCESS;
}

MA_API void ma_node_graph_uninit(ma_node_graph* pNodeGraph, const ma_allocation_callbacks* pAllocationCallbacks)
{
    if (pNodeGraph == NULL) {
        return;
    }

    ma_node_uninit(&pNodeGraph->endpoint, pAllocationCallbacks);
}

MA_API ma_node* ma_node_graph_get_endpoint(ma_node_graph* pNodeGraph)
{
    if (pNodeGraph == NULL) {
        return NULL;
    }

    return &pNodeGraph->endpoint;
}

MA_API ma_result ma_node_graph_read_pcm_frames(ma_node_graph* pNodeGraph, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
    ma_result result = MA_SUCCESS;
    ma_uint64 totalFramesRead;
    ma_uint32 channels;

    if (pFramesRead != NULL) {
        *pFramesRead = 0;   /* Safety. */
    }

    if (pNodeGraph == NULL) {
        return MA_INVALID_ARGS;
    }

    channels = ma_node_get_output_channels(&pNodeGraph->endpoint, 0);


    /* We'll be nice and try to do a full read of all frameCount frames. */
    totalFramesRead = 0;
    while (totalFramesRead < frameCount) {
        ma_uint32 framesJustRead;
        ma_uint64 framesToRead = frameCount - totalFramesRead;

        if (framesToRead > 0xFFFFFFFF) {
            framesToRead = 0xFFFFFFFF;
        }

        ma_node_graph_set_is_reading(pNodeGraph, MA_TRUE);
        {
            result = ma_node_read_pcm_frames(&pNodeGraph->endpoint, 0, (float*)ma_offset_pcm_frames_ptr(pFramesOut, totalFramesRead, ma_format_f32, channels), (ma_uint32)framesToRead, &framesJustRead, ma_node_get_time(&pNodeGraph->endpoint));
        }
        ma_node_graph_set_is_reading(pNodeGraph, MA_FALSE);

        totalFramesRead += framesJustRead;

        if (result != MA_SUCCESS) {
            break;
        }

        /* Abort if we weren't able to read any frames or else we risk getting stuck in a loop. */

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN


    return result;
}

MA_API ma_uint32 ma_node_graph_get_channels(const ma_node_graph* pNodeGraph)
{
    if (pNodeGraph == NULL) {
        return 0;
    }

    return ma_node_get_output_channels(&pNodeGraph->endpoint, 0);
}

MA_API ma_uint64 ma_node_graph_get_time(const ma_node_graph* pNodeGraph)
{
    if (pNodeGraph == NULL) {
        return 0;
    }

    return ma_node_get_time(&pNodeGraph->endpoint); /* Global time is just the local time of the endpoint. */
}

MA_API ma_result ma_node_graph_set_time(ma_node_graph* pNodeGraph, ma_uint64 globalTime)
{
    if (pNodeGraph == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_node_set_time(&pNodeGraph->endpoint, globalTime); /* Global time is just the local time of the endpoint. */
}


#define MA_NODE_OUTPUT_BUS_FLAG_HAS_READ    0x01    /* Whether or not this bus ready to read more data. Only used on nodes with multiple output buses. */

static ma_result ma_node_output_bus_init(ma_node* pNode, ma_uint32 outputBusIndex, ma_uint32 channels, ma_node_output_bus* pOutputBus)
{
    MA_ASSERT(pOutputBus != NULL);
    MA_ASSERT(outputBusIndex < MA_MAX_NODE_BUS_COUNT);
    MA_ASSERT(outputBusIndex < ma_node_get_output_bus_count(pNode));

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

            return ma_device_get_log(ma_engine_get_device(pEngine));
        }
        #else
        {
            return NULL;
        }
        #endif
    }
}

MA_API ma_node* ma_engine_get_endpoint(ma_engine* pEngine)
{
    return ma_node_graph_get_endpoint(&pEngine->nodeGraph);
}

MA_API ma_uint64 ma_engine_get_time(const ma_engine* pEngine)
{
    return ma_node_graph_get_time(&pEngine->nodeGraph);
}

MA_API ma_result ma_engine_set_time(ma_engine* pEngine, ma_uint64 globalTime)
{
    return ma_node_graph_set_time(&pEngine->nodeGraph, globalTime);

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN


    return MA_SUCCESS;
}

MA_API ma_result ma_engine_set_volume(ma_engine* pEngine, float volume)
{
    if (pEngine == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_node_set_output_bus_volume(ma_node_graph_get_endpoint(&pEngine->nodeGraph), 0, volume);
}

MA_API ma_result ma_engine_set_gain_db(ma_engine* pEngine, float gainDB)
{
    if (pEngine == NULL) {
        return MA_INVALID_ARGS;
    }

    return ma_node_set_output_bus_volume(ma_node_graph_get_endpoint(&pEngine->nodeGraph), 0, ma_volume_db_to_linear(gainDB));
}


MA_API ma_uint32 ma_engine_get_listener_count(const ma_engine* pEngine)
{
    if (pEngine == NULL) {
        return 0;
    }

    return pEngine->listenerCount;

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

MA_API ma_result ma_engine_play_sound_ex(ma_engine* pEngine, const char* pFilePath, ma_node* pNode, ma_uint32 nodeInputBusIndex)
{
    ma_result result = MA_SUCCESS;
    ma_sound_inlined* pSound = NULL;
    ma_sound_inlined* pNextSound = NULL;

    if (pEngine == NULL || pFilePath == NULL) {
        return MA_INVALID_ARGS;
    }

    /* Attach to the endpoint node if nothing is specicied. */
    if (pNode == NULL) {
        pNode = ma_node_graph_get_endpoint(&pEngine->nodeGraph);
        nodeInputBusIndex = 0;
    }

    /*
    We want to check if we can recycle an already-allocated inlined sound. Since this is just a
    helper I'm not *too* concerned about performance here and I'm happy to use a lock to keep
    the implementation simple. Maybe this can be optimized later if there's enough demand, but
    if this function is being used it probably means the caller doesn't really care too much.

    What we do is check the atEnd flag. When this is true, we can recycle the sound. Otherwise

share/public_html/static/music_worklet_inprogress/decoder/deps/miniaudio/miniaudio.h  view on Meta::CPAN

        }
    }


    /* Getting here means we should have a valid channel count and we can initialize the engine node. */
    result = ma_engine_node_init(&engineNodeConfig, &pEngine->allocationCallbacks, &pSound->engineNode);
    if (result != MA_SUCCESS) {
        return result;
    }

    /* If no attachment is specified, attach the sound straight to the endpoint. */
    if (pConfig->pInitialAttachment == NULL) {
        /* No group. Attach straight to the endpoint by default, unless the caller has requested that do not. */
        if ((pConfig->flags & MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT) == 0) {
            result = ma_node_attach_output_bus(pSound, 0, ma_node_graph_get_endpoint(&pEngine->nodeGraph), 0);
        }
    } else {
        /* An attachment is specified. Attach to it by default. The sound has only a single output bus, and the config will specify which input bus to attach to. */
        result = ma_node_attach_output_bus(pSound, 0, pConfig->pInitialAttachment, pConfig->initialAttachmentInputBusIndex);
    }

    if (result != MA_SUCCESS) {
        ma_engine_node_uninit(&pSound->engineNode, &pEngine->allocationCallbacks);
        return result;
    }



( run in 0.284 second using v1.01-cache-2.11-cpan-27979f6cc8f )