pvrecorder/src/miniaudio/research/_examples/resource_manager_advanced.c
Go to the documentation of this file.
1 /*
2 Demonstrates how you can use the resource manager to manage loaded sounds.
3 
4 The resource manager can be used to create a data source whose resources are managed internally by miniaudio. The data
5 sources can then be read just like any other data source such as decoders and audio buffers.
6 
7 In this example we use the resource manager independently of the `ma_engine` API so that we can demonstrate how it can
8 be used by itself without getting it confused with `ma_engine`.
9 
10 The main feature of the resource manager is the ability to decode and stream audio data asynchronously. Asynchronicity
11 is achieved with a job system. The resource manager will issue jobs which are processed by a configurable number of job
12 threads. You can also implement your own custom job threads which this example also demonstrates.
13 
14 In this example we show how you can create a data source, mix them with other data sources, configure the number of job
15 threads to manage internally and how to implement your own custom job thread.
16 */
17 #define MA_NO_ENGINE /* We're intentionally not using the ma_engine API here. */
18 #define MINIAUDIO_IMPLEMENTATION
19 #include "../../miniaudio.h"
20 #include "../miniaudio_engine.h"
21 
24 
25 
26 /*
27 TODO: Consider putting these public functions in miniaudio.h. Will depend on ma_mix_pcm_frames_f32()
28 being merged into miniaudio.h (it's currently in miniaudio_engine.h).
29 */
30 static ma_result ma_data_source_read_pcm_frames_f32_ex(ma_data_source* pDataSource, float* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead, ma_bool32 loop, ma_format dataSourceFormat, ma_uint32 dataSourceChannels)
31 {
32  /*
33  This function is intended to be used when the format and channel count of the data source is
34  known beforehand. The idea is to avoid overhead due to redundant calls to ma_data_source_get_data_format().
35  */
36  MA_ASSERT(pDataSource != NULL);
37 
38  if (dataSourceFormat == ma_format_f32) {
39  /* Fast path. No conversion necessary. */
40  return ma_data_source_read_pcm_frames(pDataSource, pFramesOut, frameCount, pFramesRead, loop);
41  } else {
42  /* Slow path. Conversion necessary. */
43  ma_result result;
44  ma_uint64 totalFramesRead;
46  ma_uint64 tempCapInFrames = sizeof(temp) / ma_get_bytes_per_frame(dataSourceFormat, dataSourceChannels);
47 
48  totalFramesRead = 0;
49  while (totalFramesRead < frameCount) {
50  ma_uint64 framesJustRead;
51  ma_uint64 framesToRead = frameCount - totalFramesRead;
52  if (framesToRead > tempCapInFrames) {
53  framesToRead = tempCapInFrames;
54  }
55 
56  result = ma_data_source_read_pcm_frames(pDataSource, pFramesOut, framesToRead, &framesJustRead, loop);
57 
58  ma_convert_pcm_frames_format(ma_offset_pcm_frames_ptr_f32(pFramesOut, totalFramesRead, dataSourceChannels), ma_format_f32, temp, dataSourceFormat, framesJustRead, dataSourceChannels, ma_dither_mode_none);
59  totalFramesRead += framesJustRead;
60 
61  if (result != MA_SUCCESS) {
62  break;
63  }
64  }
65 
66  return MA_SUCCESS;
67  }
68 }
69 
70 MA_API ma_result ma_data_source_read_pcm_frames_f32(ma_data_source* pDataSource, float* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead, ma_bool32 loop)
71 {
72  ma_result result;
73  ma_format format;
74  ma_uint32 channels;
75 
76  result = ma_data_source_get_data_format(pDataSource, &format, &channels, NULL);
77  if (result != MA_SUCCESS) {
78  return result; /* Failed to retrieve the data format of the data source. */
79  }
80 
81  return ma_data_source_read_pcm_frames_f32_ex(pDataSource, pFramesOut, frameCount, pFramesRead, loop, format, channels);
82 }
83 
84 MA_API ma_result ma_data_source_read_pcm_frames_and_mix_f32(ma_data_source* pDataSource, float* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead, ma_bool32 loop, float volume)
85 {
86  ma_result result;
87  ma_format format;
88  ma_uint32 channels;
89  ma_uint64 totalFramesRead;
90 
91  if (pFramesRead != NULL) {
92  *pFramesRead = 0;
93  }
94 
95  if (pDataSource == NULL) {
96  return MA_INVALID_ARGS;
97  }
98 
99  result = ma_data_source_get_data_format(pDataSource, &format, &channels, NULL);
100  if (result != MA_SUCCESS) {
101  return result; /* Failed to retrieve the data format of the data source. */
102  }
103 
104  totalFramesRead = 0;
105  while (totalFramesRead < frameCount) {
106  float temp[MA_DATA_CONVERTER_STACK_BUFFER_SIZE/sizeof(float)];
107  ma_uint64 tempCapInFrames = ma_countof(temp) / channels;
108  ma_uint64 framesJustRead;
109  ma_uint64 framesToRead = frameCount - totalFramesRead;
110  if (framesToRead > tempCapInFrames) {
111  framesToRead = tempCapInFrames;
112  }
113 
114  result = ma_data_source_read_pcm_frames_f32_ex(pDataSource, temp, framesToRead, &framesJustRead, loop, format, channels);
115 
116  ma_mix_pcm_frames_f32(ma_offset_pcm_frames_ptr(pFramesOut, totalFramesRead, ma_format_f32, channels), temp, framesJustRead, channels, volume);
117  totalFramesRead += framesJustRead;
118 
119  if (result != MA_SUCCESS) {
120  break;
121  }
122  }
123 
124  if (pFramesRead != NULL) {
125  *pFramesRead = totalFramesRead;
126  }
127 
128  return MA_SUCCESS;
129 }
130 
131 
132 void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
133 {
134  /*
135  In this example we're just going to play our data sources layered on top of each other. This
136  assumes the device's format is f32 and that the buffer is not pre-silenced.
137  */
138  ma_uint32 iDataSource;
139 
140  MA_ASSERT(pDevice->playback.format == ma_format_f32);
141 
142  (void)pInput; /* Unused. */
143 
144  /*
145  If the device was configured with noPreSilencedOutputBuffer then you would need to silence the
146  buffer here, or make sure the first data source to be mixed is copied rather than mixed.
147  */
148  /*ma_silence_pcm_frames(pOutput, frameCount, ma_format_f32, pDevice->playback.channels);*/
149 
150  /* For each sound, mix as much data as we can. */
151  for (iDataSource = 0; iDataSource < g_dataSourceCount; iDataSource += 1) {
152  ma_data_source_read_pcm_frames_and_mix_f32(&g_dataSources[iDataSource], (float*)pOutput, frameCount, NULL, MA_TRUE, /* volume = */1);
153  }
154 }
155 
157 {
158  ma_resource_manager* pResourceManager = (ma_resource_manager*)pUserData;
159  MA_ASSERT(pResourceManager != NULL);
160 
161  for (;;) {
162  ma_result result;
163  ma_job job;
164 
165  /*
166  Retrieve a job from the queue first. This defines what it is you're about to do. By default this will be
167  blocking. You can initialize the resource manager with MA_RESOURCE_MANAGER_FLAG_NON_BLOCKING to not block in
168  which case MA_NO_DATA_AVAILABLE will be returned if no jobs are available.
169 
170  When the quit job is returned (MA_JOB_QUIT), the return value will always be MA_CANCELLED. If you don't want
171  to check the return value (you should), you can instead check if the job code is MA_JOB_QUIT and use that
172  instead.
173  */
174  result = ma_resource_manager_next_job(pResourceManager, &job);
175  if (result != MA_SUCCESS) {
176  if (result == MA_CANCELLED) {
177  printf("CUSTOM JOB THREAD TERMINATING VIA MA_CANCELLED... ");
178  } else {
179  printf("CUSTOM JOB THREAD ERROR: %s. TERMINATING... ", ma_result_description(result));
180  }
181 
182  break;
183  }
184 
185  /*
186  Terminate if we got a quit message. You don't need to terminate like this, but's a bit more robust. You can
187  just use a global variable or something similar if it's easier for your particular situation. The quit job
188  remains in the queue and will continue to be returned by future calls to ma_resource_manager_next_job(). The
189  reason for this is to give every job thread visibility to the quit job so they have a chance to exit.
190 
191  We won't actually be hitting this code because the call above will return MA_CANCELLED when the MA_JOB_QUIT
192  event is received which means the `result != MA_SUCCESS` logic above will catch it. If you do not check the
193  return value of ma_resource_manager_next_job() you will want to check for MA_JOB_QUIT like the code below.
194  */
195  if (job.toc.breakup.code == MA_JOB_QUIT) {
196  printf("CUSTOM JOB THREAD TERMINATING VIA MA_JOB_QUIT... ");
197  break;
198  }
199 
200  /* Call ma_resource_manager_process_job() to actually do the work to process the job. */
201  printf("PROCESSING IN CUSTOM JOB THREAD: %d\n", job.toc.breakup.code);
202  ma_resource_manager_process_job(pResourceManager, &job);
203  }
204 
205  printf("TERMINATED\n");
206  return (ma_thread_result)0;
207 }
208 
209 int main(int argc, char** argv)
210 {
211  ma_result result;
212  ma_device_config deviceConfig;
214  ma_resource_manager_config resourceManagerConfig;
215  ma_resource_manager resourceManager;
216  ma_thread jobThread;
217  int iFile;
218 
220  deviceConfig.playback.format = ma_format_f32;
221  deviceConfig.dataCallback = data_callback;
222  deviceConfig.pUserData = NULL;
223 
224  result = ma_device_init(NULL, &deviceConfig, &device);
225  if (result != MA_SUCCESS) {
226  printf("Failed to initialize device.");
227  return -1;
228  }
229 
230 
231  /* We can start the device before loading any sounds. We'll just end up outputting silence. */
232  result = ma_device_start(&device);
233  if (result != MA_SUCCESS) {
235  printf("Failed to start device.");
236  return -1;
237  }
238 
239 
240  /*
241  We have the device so now we want to initialize the resource manager. We'll use the resource manager to load some
242  sounds based on the command line.
243  */
244  resourceManagerConfig = ma_resource_manager_config_init();
245 
246  /*
247  We'll set a standard decoding format to save us to processing time at mixing time. If you're wanting to use
248  spatialization with your decoded sounds, you may want to consider leaving this as 0 to ensure the file's native
249  channel count is used so you can do proper spatialization.
250  */
251  resourceManagerConfig.decodedFormat = device.playback.format;
252  resourceManagerConfig.decodedChannels = device.playback.channels;
253  resourceManagerConfig.decodedSampleRate = device.sampleRate;
254 
255  /* The number of job threads to be managed internally. Set this to 0 if you want to self-manage your job threads */
256  resourceManagerConfig.jobThreadCount = 4;
257 
258  result = ma_resource_manager_init(&resourceManagerConfig, &resourceManager);
259  if (result != MA_SUCCESS) {
261  printf("Failed to initialize the resource manager.");
262  return -1;
263  }
264 
265  /*
266  Now that we have a resource manager we can set up our custom job thread. This is optional. Normally when doing
267  self-managed job threads you would set the internal job thread count to zero. We're doing both internal and
268  self-managed job threads in this example just for demonstration purposes.
269  */
270  ma_thread_create(&jobThread, ma_thread_priority_default, 0, custom_job_thread, &resourceManager, NULL);
271 
272  /* Create each data source from the resource manager. Note that the caller is the owner. */
273  for (iFile = 0; iFile < ma_countof(g_dataSources) && iFile < argc-1; iFile += 1) {
275  &resourceManager,
276  argv[iFile+1],
277  MA_DATA_SOURCE_FLAG_DECODE | MA_DATA_SOURCE_FLAG_ASYNC /*| MA_DATA_SOURCE_FLAG_STREAM*/,
278  NULL, /* Async notification. */
279  &g_dataSources[iFile]);
280 
281  if (result != MA_SUCCESS) {
282  break;
283  }
284 
285  g_dataSourceCount += 1;
286  }
287 
288  printf("Press Enter to quit...");
289  getchar();
290 
291 
292  /* Teardown. */
293 
294  /*
295  Uninitialize the device first to ensure the data callback is stopped and doesn't try to access
296  any data.
297  */
299 
300  /*
301  Our data sources need to be explicitly uninitialized. ma_resource_manager_uninit() will not do
302  it for us. This needs to be done before posting the quit event and uninitializing the resource
303  manager or else we'll get stuck in a deadlock because ma_resource_manager_data_source_uninit()
304  will be waiting for the job thread(s) to finish work, which will never happen because they were
305  just terminated.
306  */
307  for (iFile = 0; (size_t)iFile < g_dataSourceCount; iFile += 1) {
309  }
310 
311  /*
312  Before uninitializing the resource manager we need to make sure a quit event has been posted to
313  ensure we can get out of our custom thread. The call to ma_resource_manager_uninit() will also
314  do this, but we need to call it explicitly so that our self-managed thread can exit naturally.
315  You only need to post a quit job if you're using that as the exit indicator. You can instead
316  use whatever variable you want to terminate your job thread, but since this example is using a
317  quit job we need to post one. Note that you don't need to do this if you're not managing your
318  own threads - ma_resource_manager_uninit() alone will suffice in that case.
319  */
320  ma_resource_manager_post_job_quit(&resourceManager);
321  ma_thread_wait(&jobThread); /* Wait for the custom job thread to finish so it doesn't try to access any data. */
322 
323  /* Uninitialize the resource manager after each data source. */
324  ma_resource_manager_uninit(&resourceManager);
325 
326  return 0;
327 }
ma_uint64
uint64_t ma_uint64
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1505
ma_get_bytes_per_frame
static MA_INLINE ma_uint32 ma_get_bytes_per_frame(ma_format format, ma_uint32 channels)
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:2673
ma_resource_manager_config::decodedChannels
ma_uint32 decodedChannels
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/miniaudio_engine.h:1516
ma_resource_manager_config::decodedSampleRate
ma_uint32 decodedSampleRate
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/miniaudio_engine.h:1517
ma_thread
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:2824
ma_job::breakup
struct ma_job::@270::@273 breakup
MA_INVALID_ARGS
#define MA_INVALID_ARGS
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1661
ma_uint8
uint8_t ma_uint8
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1499
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
ma_resource_manager_data_source_init
MA_API ma_result ma_resource_manager_data_source_init(ma_resource_manager *pResourceManager, const char *pName, ma_uint32 flags, const ma_pipeline_notifications *pNotifications, ma_resource_manager_data_source *pDataSource)
MA_CANCELLED
#define MA_CANCELLED
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1710
NULL
#define NULL
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:92
ma_data_source_read_pcm_frames_f32_ex
static ma_result ma_data_source_read_pcm_frames_f32_ex(ma_data_source *pDataSource, float *pFramesOut, ma_uint64 frameCount, ma_uint64 *pFramesRead, ma_bool32 loop, ma_format dataSourceFormat, ma_uint32 dataSourceChannels)
Definition: pvrecorder/src/miniaudio/research/_examples/resource_manager_advanced.c:30
ma_device::channels
ma_uint32 channels
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3626
ma_bool32
ma_uint32 ma_bool32
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1529
ma_data_source_read_pcm_frames
MA_API ma_result ma_data_source_read_pcm_frames(ma_data_source *pDataSource, void *pFramesOut, ma_uint64 frameCount, ma_uint64 *pFramesRead, ma_bool32 loop)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:37348
ma_countof
#define ma_countof(x)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:776
ma_format_f32
@ ma_format_f32
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1790
ma_resource_manager_post_job_quit
MA_API ma_result ma_resource_manager_post_job_quit(ma_resource_manager *pResourceManager)
MA_DATA_CONVERTER_STACK_BUFFER_SIZE
#define MA_DATA_CONVERTER_STACK_BUFFER_SIZE
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:4226
ma_data_source
void ma_data_source
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.h:4500
ma_format
ma_format
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1779
ma_offset_pcm_frames_ptr_f32
static MA_INLINE float * ma_offset_pcm_frames_ptr_f32(float *p, ma_uint64 offsetInFrames, ma_uint32 channels)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.h:4447
MA_API
#define MA_API
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.h:174
ma_device::format
ma_format format
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3625
ma_data_source_read_pcm_frames_and_mix_f32
MA_API ma_result ma_data_source_read_pcm_frames_and_mix_f32(ma_data_source *pDataSource, float *pFramesOut, ma_uint64 frameCount, ma_uint64 *pFramesRead, ma_bool32 loop, float volume)
Definition: pvrecorder/src/miniaudio/research/_examples/resource_manager_advanced.c:84
ma_device_type_playback
@ ma_device_type_playback
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3012
ma_resource_manager_data_source_uninit
MA_API ma_result ma_resource_manager_data_source_uninit(ma_resource_manager_data_source *pDataSource)
MA_DATA_SOURCE_FLAG_ASYNC
#define MA_DATA_SOURCE_FLAG_ASYNC
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/miniaudio_engine.h:1123
ma_device_config::dataCallback
ma_device_callback_proc dataCallback
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3110
ma_thread_result
void * ma_thread_result
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:4266
ma_data_source_read_pcm_frames_f32
MA_API ma_result ma_data_source_read_pcm_frames_f32(ma_data_source *pDataSource, float *pFramesOut, ma_uint64 frameCount, ma_uint64 *pFramesRead, ma_bool32 loop)
Definition: pvrecorder/src/miniaudio/research/_examples/resource_manager_advanced.c:70
ma_dither_mode_none
@ ma_dither_mode_none
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1774
device
ma_device device
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_deviceio/ma_test_deviceio.c:57
ma_result_description
const char * ma_result_description(ma_result result)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:37039
ma_result
int ma_result
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1658
g_dataSources
static ma_resource_manager_data_source g_dataSources[16]
Definition: pvrecorder/src/miniaudio/research/_examples/resource_manager_advanced.c:22
MA_THREADCALL
#define MA_THREADCALL
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:4265
ma_resource_manager_uninit
MA_API void ma_resource_manager_uninit(ma_resource_manager *pResourceManager)
ma_resource_manager_init
MA_API ma_result ma_resource_manager_init(const ma_resource_manager_config *pConfig, ma_resource_manager *pResourceManager)
ma_resource_manager_config::jobThreadCount
ma_uint32 jobThreadCount
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/miniaudio_engine.h:1518
ma_thread_wait
static void ma_thread_wait(ma_thread *pThread)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:4754
ma_resource_manager_config
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/miniaudio_engine.h:1511
MA_DATA_SOURCE_FLAG_DECODE
#define MA_DATA_SOURCE_FLAG_DECODE
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/miniaudio_engine.h:1122
ma_resource_manager_process_job
MA_API ma_result ma_resource_manager_process_job(ma_resource_manager *pResourceManager, ma_job *pJob)
MA_ASSERT
#define MA_ASSERT(condition)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:770
ma_offset_pcm_frames_ptr
MA_API void * ma_offset_pcm_frames_ptr(void *p, ma_uint64 offsetInFrames, ma_format format, ma_uint32 channels)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:27802
ma_resource_manager
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/miniaudio_engine.h:1528
MA_JOB_QUIT
#define MA_JOB_QUIT
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/miniaudio_engine.h:1139
ma_resource_manager_config_init
MA_API ma_resource_manager_config ma_resource_manager_config_init(void)
ma_job
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/miniaudio_engine.h:1268
ma_uint32
uint32_t ma_uint32
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1503
data_callback
void data_callback(ma_device *pDevice, void *pOutput, const void *pInput, ma_uint32 frameCount)
Definition: pvrecorder/src/miniaudio/research/_examples/resource_manager_advanced.c:132
ma_device_config::format
ma_format format
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3128
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_resource_manager_config::decodedFormat
ma_format decodedFormat
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/miniaudio_engine.h:1515
custom_job_thread
static ma_thread_result MA_THREADCALL custom_job_thread(void *pUserData)
Definition: pvrecorder/src/miniaudio/research/_examples/resource_manager_advanced.c:156
ma_resource_manager_next_job
MA_API ma_result ma_resource_manager_next_job(ma_resource_manager *pResourceManager, ma_job *pJob)
ma_resource_manager_data_source
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/research/miniaudio_engine.h:1498
ma_job::toc
union ma_job::@270 toc
ma_thread_create
static ma_result ma_thread_create(ma_thread *pThread, ma_thread_priority priority, size_t stackSize, ma_thread_entry_proc entryProc, void *pData, const ma_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:4721
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
g_dataSourceCount
static ma_uint32 g_dataSourceCount
Definition: pvrecorder/src/miniaudio/research/_examples/resource_manager_advanced.c:23
MA_TRUE
#define MA_TRUE
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1530
MA_SUCCESS
#define MA_SUCCESS
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1659
ma_thread_priority_default
@ ma_thread_priority_default
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:2821
ma_data_source_get_data_format
MA_API ma_result ma_data_source_get_data_format(ma_data_source *pDataSource, ma_format *pFormat, ma_uint32 *pChannels, ma_uint32 *pSampleRate)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:37609
main
int main(int argc, char **argv)
Definition: pvrecorder/src/miniaudio/research/_examples/resource_manager_advanced.c:209
ma_convert_pcm_frames_format
void ma_convert_pcm_frames_format(void *pOut, ma_format formatOut, const void *pIn, ma_format formatIn, ma_uint64 frameCount, ma_uint32 channels, ma_dither_mode ditherMode)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:30307
ma_device_config::playback
struct ma_device_config::@97 playback
ma_device::playback
struct ma_device::@115 playback
ma_device_config::pUserData
void * pUserData
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3112


picovoice_driver
Author(s):
autogenerated on Fri Apr 1 2022 02:14:50