pvrecorder/src/miniaudio/research/_examples/duplex_effect.c
Go to the documentation of this file.
1 /*
2 Demonstrates how to apply an effect to a duplex stream using the node graph system.
3 
4 This example applies a vocoder effect to the input stream before outputting it. A custom node
5 called `ma_vocoder_node` is used to achieve the effect which can be found in the extras folder in
6 the miniaudio repository. The vocoder node uses https://github.com/blastbay/voclib to achieve the
7 effect.
8 */
9 #define MINIAUDIO_IMPLEMENTATION
10 #include "../../miniaudio.h"
11 #include "../miniaudio_engine.h"
12 #include "../_extras/nodes/ma_vocoder_node/ma_vocoder_node.c"
13 
14 #include <stdio.h>
15 
16 #define DEVICE_FORMAT ma_format_f32; /* Must always be f32 for this example because the node graph system only works with this. */
17 #define DEVICE_CHANNELS 1 /* For this example, always set to 1. */
18 
19 static ma_waveform g_sourceData; /* The underlying data source of the excite node. */
20 static ma_audio_buffer_ref g_exciteData; /* The underlying data source of the source node. */
21 static ma_data_source_node g_sourceNode; /* A data source node containing the source data we'll be sending through to the vocoder. This will be routed into the first bus of the vocoder node. */
22 static ma_data_source_node g_exciteNode; /* A data source node containing the excite data we'll be sending through to the vocoder. This will be routed into the second bus of the vocoder node. */
23 static ma_vocoder_node g_vocoderNode; /* The vocoder node. */
25 
26 void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
27 {
28  MA_ASSERT(pDevice->capture.format == pDevice->playback.format);
29  MA_ASSERT(pDevice->capture.channels == pDevice->playback.channels);
30 
31  /*
32  The node graph system is a pulling style of API. At the lowest level of the chain will be a
33  node acting as a data source for the purpose of delivering the initial audio data. In our case,
34  the data source is our `pInput` buffer. We need to update the underlying data source so that it
35  read data from `pInput`.
36  */
37  ma_audio_buffer_ref_set_data(&g_exciteData, pInput, frameCount);
38 
39  /* With the source buffer configured we can now read directly from the node graph. */
40  ma_node_graph_read_pcm_frames(&g_nodeGraph, pOutput, frameCount, NULL);
41 }
42 
43 int main(int argc, char** argv)
44 {
45  ma_result result;
46  ma_device_config deviceConfig;
48  ma_node_graph_config nodeGraphConfig;
49  ma_vocoder_node_config vocoderNodeConfig;
50  ma_data_source_node_config sourceNodeConfig;
51  ma_data_source_node_config exciteNodeConfig;
52  ma_waveform_config waveformConfig;
53 
55  deviceConfig.capture.pDeviceID = NULL;
56  deviceConfig.capture.format = DEVICE_FORMAT;
57  deviceConfig.capture.channels = DEVICE_CHANNELS;
58  deviceConfig.capture.shareMode = ma_share_mode_shared;
59  deviceConfig.playback.pDeviceID = NULL;
60  deviceConfig.playback.format = DEVICE_FORMAT;
61  deviceConfig.playback.channels = DEVICE_CHANNELS;
62  deviceConfig.dataCallback = data_callback;
63  result = ma_device_init(NULL, &deviceConfig, &device);
64  if (result != MA_SUCCESS) {
65  return result;
66  }
67 
68 
69  /* Now we can setup our node graph. */
71 
72  result = ma_node_graph_init(&nodeGraphConfig, NULL, &g_nodeGraph);
73  if (result != MA_SUCCESS) {
74  printf("Failed to initialize node graph.");
75  goto done0;
76  }
77 
78 
79  /* Vocoder. Attached straight to the endpoint. */
81 
82  result = ma_vocoder_node_init(&g_nodeGraph, &vocoderNodeConfig, NULL, &g_vocoderNode);
83  if (result != MA_SUCCESS) {
84  printf("Failed to initialize vocoder node.");
85  goto done1;
86  }
87 
89 
90  /* Amplify the volume of the vocoder output because in my testing it is a bit quiet. */
92 
93 
94  /* Source/carrier. Attached to input bus 0 of the vocoder node. */
96 
97  result = ma_waveform_init(&waveformConfig, &g_sourceData);
98  if (result != MA_SUCCESS) {
99  printf("Failed to initialize waveform for excite node.");
100  goto done3;
101  }
102 
104 
105  result = ma_data_source_node_init(&g_nodeGraph, &sourceNodeConfig, NULL, &g_sourceNode);
106  if (result != MA_SUCCESS) {
107  printf("Failed to initialize excite node.");
108  goto done3;
109  }
110 
112 
113 
114  /* Excite/modulator. Attached to input bus 1 of the vocoder node. */
116  if (result != MA_SUCCESS) {
117  printf("Failed to initialize audio buffer for source.");
118  goto done2;
119  }
120 
122 
123  result = ma_data_source_node_init(&g_nodeGraph, &exciteNodeConfig, NULL, &g_exciteNode);
124  if (result != MA_SUCCESS) {
125  printf("Failed to initialize source node.");
126  goto done2;
127  }
128 
130 
131 
133 
134  printf("Press Enter to quit...\n");
135  getchar();
136 
137  /* It's important that we stop the device first or else we'll uninitialize the graph from under the device. */
139 
144 done0: ma_device_uninit(&device);
145 
146  (void)argc;
147  (void)argv;
148  return 0;
149 }
ma_device_config::pDeviceID
ma_device_id * pDeviceID
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3127
ma_device_config::shareMode
ma_share_mode shareMode
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3131
MA_FALSE
#define MA_FALSE
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1531
ma_data_source_node_config
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/miniaudio_engine.h:1073
g_exciteData
static ma_audio_buffer_ref g_exciteData
Definition: pvrecorder/src/miniaudio/research/_examples/duplex_effect.c:20
ma_device_uninit
void ma_device_uninit(ma_device *pDevice)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:27425
ma_device_start
ma_result ma_device_start(ma_device *pDevice)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:27485
NULL
#define NULL
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:92
ma_device::channels
ma_uint32 channels
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3626
ma_waveform_config
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5361
ma_node_graph_read_pcm_frames
MA_API ma_result ma_node_graph_read_pcm_frames(ma_node_graph *pNodeGraph, void *pFramesOut, ma_uint32 frameCount, ma_uint32 *pFramesRead)
ma_device_stop
ma_result ma_device_stop(ma_device *pDevice)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:27544
ma_device::format
ma_format format
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3625
ma_audio_buffer_ref_set_data
MA_API ma_result ma_audio_buffer_ref_set_data(ma_audio_buffer_ref *pAudioBufferRef, const void *pData, ma_uint64 sizeInFrames)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:38077
g_exciteNode
static ma_data_source_node g_exciteNode
Definition: pvrecorder/src/miniaudio/research/_examples/duplex_effect.c:22
ma_vocoder_node
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/ma_vocoder_node.h:33
ma_node_graph_config
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/miniaudio_engine.h:1045
ma_device_config::dataCallback
ma_device_callback_proc dataCallback
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3110
main
int main(int argc, char **argv)
Definition: pvrecorder/src/miniaudio/research/_examples/duplex_effect.c:43
ma_vocoder_node_uninit
MA_API void ma_vocoder_node_uninit(ma_vocoder_node *pVocoderNode, const ma_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/ma_vocoder_node.c:76
ma_node_graph_config_init
MA_API ma_node_graph_config ma_node_graph_config_init(ma_uint32 channels)
ma_vocoder_node_config_init
MA_API ma_vocoder_node_config ma_vocoder_node_config_init(ma_uint32 channels, ma_uint32 sampleRate)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/ma_vocoder_node.c:5
device
ma_device device
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_deviceio/ma_test_deviceio.c:57
ma_waveform_type_sawtooth
@ ma_waveform_type_sawtooth
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5362
ma_device_config::capture
struct ma_device_config::@98 capture
ma_vocoder_node_init
MA_API ma_result ma_vocoder_node_init(ma_node_graph *pNodeGraph, const ma_vocoder_node_config *pConfig, const ma_allocation_callbacks *pAllocationCallbacks, ma_vocoder_node *pVocoderNode)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/ma_vocoder_node.c:38
ma_result
int ma_result
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1658
g_nodeGraph
static ma_node_graph g_nodeGraph
Definition: pvrecorder/src/miniaudio/research/_examples/duplex_effect.c:24
ma_node_set_output_bus_volume
MA_API ma_result ma_node_set_output_bus_volume(ma_node *pNode, ma_uint32 outputBusIndex, float volume)
ma_waveform_init
ma_result ma_waveform_init(const ma_waveform_config *pConfig, ma_waveform *pWaveform)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:45445
ma_share_mode_shared
@ ma_share_mode_shared
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3020
ma_data_source_node_config_init
MA_API ma_data_source_node_config ma_data_source_node_config_init(ma_data_source *pDataSource, ma_bool32 looping)
ma_audio_buffer_ref_init
MA_API ma_result ma_audio_buffer_ref_init(ma_format format, ma_uint32 channels, const void *pData, ma_uint64 sizeInFrames, ma_audio_buffer_ref *pAudioBufferRef)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:38040
DEVICE_FORMAT
#define DEVICE_FORMAT
Definition: pvrecorder/src/miniaudio/research/_examples/duplex_effect.c:16
MA_ASSERT
#define MA_ASSERT(condition)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:770
ma_waveform_config_init
ma_waveform_config ma_waveform_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, ma_waveform_type type, double amplitude, double frequency)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:45369
g_vocoderNode
static ma_vocoder_node g_vocoderNode
Definition: pvrecorder/src/miniaudio/research/_examples/duplex_effect.c:23
ma_node_graph_get_endpoint
MA_API ma_node * ma_node_graph_get_endpoint(ma_node_graph *pNodeGraph)
ma_node_graph_init
MA_API ma_result ma_node_graph_init(const ma_node_graph_config *pConfig, const ma_allocation_callbacks *pAllocationCallbacks, ma_node_graph *pNodeGraph)
ma_uint32
uint32_t ma_uint32
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1503
ma_waveform
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5373
ma_audio_buffer_ref
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.h:4562
ma_device_config::format
ma_format format
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3128
ma_data_source_node_init
MA_API ma_result ma_data_source_node_init(ma_node_graph *pNodeGraph, const ma_data_source_node_config *pConfig, const ma_allocation_callbacks *pAllocationCallbacks, ma_data_source_node *pDataSourceNode)
ma_data_source_node_uninit
MA_API void ma_data_source_node_uninit(ma_data_source_node *pDataSourceNode, const ma_allocation_callbacks *pAllocationCallbacks)
ma_device_config_init
ma_device_config ma_device_config_init(ma_device_type deviceType)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:27034
ma_node_attach_output_bus
MA_API ma_result ma_node_attach_output_bus(ma_node *pNode, ma_uint32 outputBusIndex, ma_node *pOtherNode, ma_uint32 otherNodeInputBusIndex)
g_sourceData
static ma_waveform g_sourceData
Definition: pvrecorder/src/miniaudio/research/_examples/duplex_effect.c:19
ma_device_config::channels
ma_uint32 channels
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3129
ma_node_graph
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/miniaudio_engine.h:1053
ma_data_source_node
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/miniaudio_engine.h:1083
python.test_porcupine.argv
argv
Definition: test_porcupine.py:158
ma_device_init
ma_result ma_device_init(ma_context *pContext, const ma_device_config *pConfig, ma_device *pDevice)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:27048
ma_device
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3584
ma_device_config
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3100
ma_device::sampleRate
ma_uint32 sampleRate
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3588
ma_device::capture
struct ma_device::@116 capture
ma_node_graph_uninit
MA_API void ma_node_graph_uninit(ma_node_graph *pNodeGraph, const ma_allocation_callbacks *pAllocationCallbacks)
MA_SUCCESS
#define MA_SUCCESS
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1659
g_sourceNode
static ma_data_source_node g_sourceNode
Definition: pvrecorder/src/miniaudio/research/_examples/duplex_effect.c:21
ma_vocoder_node_config
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/_extras/nodes/ma_vocoder_node/ma_vocoder_node.h:21
DEVICE_CHANNELS
#define DEVICE_CHANNELS
Definition: pvrecorder/src/miniaudio/research/_examples/duplex_effect.c:17
data_callback
void data_callback(ma_device *pDevice, void *pOutput, const void *pInput, ma_uint32 frameCount)
Definition: pvrecorder/src/miniaudio/research/_examples/duplex_effect.c:26
ma_device_config::playback
struct ma_device_config::@97 playback
ma_device_type_duplex
@ ma_device_type_duplex
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3014
ma_device::playback
struct ma_device::@115 playback


picovoice_driver
Author(s):
autogenerated on Fri Apr 1 2022 02:13:55