Initial Commit
This commit is contained in:
112
thirdparty/miniaudio-0.11.24/extras/nodes/ma_ltrim_node/ma_ltrim_node.c
vendored
Normal file
112
thirdparty/miniaudio-0.11.24/extras/nodes/ma_ltrim_node/ma_ltrim_node.c
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
#ifndef miniaudio_ltrim_node_c
|
||||
#define miniaudio_ltrim_node_c
|
||||
|
||||
#include "ma_ltrim_node.h"
|
||||
|
||||
#include <string.h> /* For memset(). */
|
||||
|
||||
#ifndef ma_min
|
||||
#define ma_min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
MA_API ma_ltrim_node_config ma_ltrim_node_config_init(ma_uint32 channels, float threshold)
|
||||
{
|
||||
ma_ltrim_node_config config;
|
||||
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.nodeConfig = ma_node_config_init(); /* Input and output channels will be set in ma_ltrim_node_init(). */
|
||||
config.channels = channels;
|
||||
config.threshold = threshold;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
static void ma_ltrim_node_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut)
|
||||
{
|
||||
ma_ltrim_node* pTrimNode = (ma_ltrim_node*)pNode;
|
||||
ma_uint32 framesProcessedIn = 0;
|
||||
ma_uint32 framesProcessedOut = 0;
|
||||
ma_uint32 channelCount = ma_node_get_input_channels(pNode, 0);
|
||||
|
||||
/*
|
||||
If we haven't yet found the start, skip over every input sample until we find a frame outside
|
||||
of the threshold.
|
||||
*/
|
||||
if (pTrimNode->foundStart == MA_FALSE) {
|
||||
while (framesProcessedIn < *pFrameCountIn) {
|
||||
ma_uint32 iChannel = 0;
|
||||
for (iChannel = 0; iChannel < channelCount; iChannel += 1) {
|
||||
float sample = ppFramesIn[0][framesProcessedIn*channelCount + iChannel];
|
||||
if (sample < -pTrimNode->threshold || sample > pTrimNode->threshold) {
|
||||
pTrimNode->foundStart = MA_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pTrimNode->foundStart) {
|
||||
break; /* The start has been found. Get out of this loop and finish off processing. */
|
||||
} else {
|
||||
framesProcessedIn += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If there's anything left, just copy it over. */
|
||||
framesProcessedOut = ma_min(*pFrameCountOut, *pFrameCountIn - framesProcessedIn);
|
||||
ma_copy_pcm_frames(ppFramesOut[0], &ppFramesIn[0][framesProcessedIn], framesProcessedOut, ma_format_f32, channelCount);
|
||||
|
||||
framesProcessedIn += framesProcessedOut;
|
||||
|
||||
/* We always "process" every input frame, but we may only done a partial output. */
|
||||
*pFrameCountIn = framesProcessedIn;
|
||||
*pFrameCountOut = framesProcessedOut;
|
||||
}
|
||||
|
||||
static ma_node_vtable g_ma_ltrim_node_vtable =
|
||||
{
|
||||
ma_ltrim_node_process_pcm_frames,
|
||||
NULL,
|
||||
1, /* 1 input bus. */
|
||||
1, /* 1 output bus. */
|
||||
MA_NODE_FLAG_DIFFERENT_PROCESSING_RATES
|
||||
};
|
||||
|
||||
MA_API ma_result ma_ltrim_node_init(ma_node_graph* pNodeGraph, const ma_ltrim_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_ltrim_node* pTrimNode)
|
||||
{
|
||||
ma_result result;
|
||||
ma_node_config baseConfig;
|
||||
|
||||
if (pTrimNode == NULL) {
|
||||
return MA_INVALID_ARGS;
|
||||
}
|
||||
|
||||
memset(pTrimNode, 0, sizeof(*pTrimNode));
|
||||
|
||||
if (pConfig == NULL) {
|
||||
return MA_INVALID_ARGS;
|
||||
}
|
||||
|
||||
pTrimNode->threshold = pConfig->threshold;
|
||||
pTrimNode->foundStart = MA_FALSE;
|
||||
|
||||
baseConfig = pConfig->nodeConfig;
|
||||
baseConfig.vtable = &g_ma_ltrim_node_vtable;
|
||||
baseConfig.pInputChannels = &pConfig->channels;
|
||||
baseConfig.pOutputChannels = &pConfig->channels;
|
||||
|
||||
result = ma_node_init(pNodeGraph, &baseConfig, pAllocationCallbacks, &pTrimNode->baseNode);
|
||||
if (result != MA_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
|
||||
MA_API void ma_ltrim_node_uninit(ma_ltrim_node* pTrimNode, const ma_allocation_callbacks* pAllocationCallbacks)
|
||||
{
|
||||
/* The base node is always uninitialized first. */
|
||||
ma_node_uninit(pTrimNode, pAllocationCallbacks);
|
||||
}
|
||||
|
||||
#endif /* miniaudio_ltrim_node_c */
|
||||
37
thirdparty/miniaudio-0.11.24/extras/nodes/ma_ltrim_node/ma_ltrim_node.h
vendored
Normal file
37
thirdparty/miniaudio-0.11.24/extras/nodes/ma_ltrim_node/ma_ltrim_node.h
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/* Include ma_ltrim_node.h after miniaudio.h */
|
||||
#ifndef miniaudio_ltrim_node_h
|
||||
#define miniaudio_ltrim_node_h
|
||||
|
||||
#include "../../../miniaudio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
The trim node has one input and one output.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ma_node_config nodeConfig;
|
||||
ma_uint32 channels;
|
||||
float threshold;
|
||||
} ma_ltrim_node_config;
|
||||
|
||||
MA_API ma_ltrim_node_config ma_ltrim_node_config_init(ma_uint32 channels, float threshold);
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ma_node_base baseNode;
|
||||
float threshold;
|
||||
ma_bool32 foundStart;
|
||||
} ma_ltrim_node;
|
||||
|
||||
MA_API ma_result ma_ltrim_node_init(ma_node_graph* pNodeGraph, const ma_ltrim_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_ltrim_node* pTrimNode);
|
||||
MA_API void ma_ltrim_node_uninit(ma_ltrim_node* pTrimNode, const ma_allocation_callbacks* pAllocationCallbacks);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* miniaudio_ltrim_node_h */
|
||||
114
thirdparty/miniaudio-0.11.24/extras/nodes/ma_ltrim_node/ma_ltrim_node_example.c
vendored
Normal file
114
thirdparty/miniaudio-0.11.24/extras/nodes/ma_ltrim_node/ma_ltrim_node_example.c
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
#include "../../../miniaudio.c"
|
||||
#include "ma_ltrim_node.c"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define DEVICE_FORMAT ma_format_f32 /* Must always be f32 for this example because the node graph system only works with this. */
|
||||
#define DEVICE_CHANNELS 0 /* The input file will determine the channel count. */
|
||||
#define DEVICE_SAMPLE_RATE 0 /* The input file will determine the sample rate. */
|
||||
|
||||
static ma_decoder g_decoder; /* The decoder that we'll read data from. */
|
||||
static ma_data_source_node g_dataSupplyNode; /* The node that will sit at the root level. Will be reading data from g_dataSupply. */
|
||||
static ma_ltrim_node g_trimNode; /* The trim node. */
|
||||
static ma_node_graph g_nodeGraph; /* The main node graph that we'll be feeding data through. */
|
||||
|
||||
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
|
||||
{
|
||||
(void)pInput;
|
||||
(void)pDevice;
|
||||
|
||||
/* All we need to do is read from the node graph. */
|
||||
ma_node_graph_read_pcm_frames(&g_nodeGraph, pOutput, frameCount, NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
ma_result result;
|
||||
ma_decoder_config decoderConfig;
|
||||
ma_device_config deviceConfig;
|
||||
ma_device device;
|
||||
ma_node_graph_config nodeGraphConfig;
|
||||
ma_ltrim_node_config trimNodeConfig;
|
||||
ma_data_source_node_config dataSupplyNodeConfig;
|
||||
|
||||
if (argc < 1) {
|
||||
printf("No input file.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Decoder. */
|
||||
decoderConfig = ma_decoder_config_init(DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE);
|
||||
|
||||
result = ma_decoder_init_file(argv[1], &decoderConfig, &g_decoder);
|
||||
if (result != MA_SUCCESS) {
|
||||
printf("Failed to load decoder.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Device. */
|
||||
deviceConfig = ma_device_config_init(ma_device_type_playback);
|
||||
deviceConfig.playback.pDeviceID = NULL;
|
||||
deviceConfig.playback.format = g_decoder.outputFormat;
|
||||
deviceConfig.playback.channels = g_decoder.outputChannels;
|
||||
deviceConfig.sampleRate = g_decoder.outputSampleRate;
|
||||
deviceConfig.dataCallback = data_callback;
|
||||
result = ma_device_init(NULL, &deviceConfig, &device);
|
||||
if (result != MA_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Node graph. */
|
||||
nodeGraphConfig = ma_node_graph_config_init(device.playback.channels);
|
||||
|
||||
result = ma_node_graph_init(&nodeGraphConfig, NULL, &g_nodeGraph);
|
||||
if (result != MA_SUCCESS) {
|
||||
printf("Failed to initialize node graph.");
|
||||
goto done0;
|
||||
}
|
||||
|
||||
|
||||
/* Trimmer. Attached straight to the endpoint. Input will be the data source node. */
|
||||
trimNodeConfig = ma_ltrim_node_config_init(device.playback.channels, 0);
|
||||
|
||||
result = ma_ltrim_node_init(&g_nodeGraph, &trimNodeConfig, NULL, &g_trimNode);
|
||||
if (result != MA_SUCCESS) {
|
||||
printf("Failed to initialize ltrim node.");
|
||||
goto done1;
|
||||
}
|
||||
|
||||
ma_node_attach_output_bus(&g_trimNode, 0, ma_node_graph_get_endpoint(&g_nodeGraph), 0);
|
||||
|
||||
|
||||
/* Data supply. */
|
||||
dataSupplyNodeConfig = ma_data_source_node_config_init(&g_decoder);
|
||||
|
||||
result = ma_data_source_node_init(&g_nodeGraph, &dataSupplyNodeConfig, NULL, &g_dataSupplyNode);
|
||||
if (result != MA_SUCCESS) {
|
||||
printf("Failed to initialize data source node.");
|
||||
goto done2;
|
||||
}
|
||||
|
||||
ma_node_attach_output_bus(&g_dataSupplyNode, 0, &g_trimNode, 0);
|
||||
|
||||
|
||||
|
||||
/* Now we just start the device and wait for the user to terminate the program. */
|
||||
ma_device_start(&device);
|
||||
|
||||
printf("Press Enter to quit...\n");
|
||||
getchar();
|
||||
|
||||
/* It's important that we stop the device first or else we'll uninitialize the graph from under the device. */
|
||||
ma_device_stop(&device);
|
||||
|
||||
|
||||
/*done3:*/ ma_data_source_node_uninit(&g_dataSupplyNode, NULL);
|
||||
done2: ma_ltrim_node_uninit(&g_trimNode, NULL);
|
||||
done1: ma_node_graph_uninit(&g_nodeGraph, NULL);
|
||||
done0: ma_device_uninit(&device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user