rhino/demo/c/dr_libs/tests/external/miniaudio/examples/fixed_size_callback.c
Go to the documentation of this file.
1 /*
2 The example demonstrates how to implement a fixed sized callback. miniaudio does not have built-in support for
3 firing the data callback with fixed sized buffers. In order to support this you need to implement a layer that
4 sits on top of the normal data callback. This example demonstrates one way of doing this.
5 
6 This example uses a ring buffer to act as the intermediary buffer between the low-level device callback and the
7 fixed sized callback. You do not need to use a ring buffer here, but it's a good opportunity to demonstrate how
8 to use miniaudio's ring buffer API. The ring buffer in this example is in global scope for simplicity, but you
9 can pass it around as user data for the device (device.pUserData).
10 
11 This only works for output devices, but can be implemented for input devices by simply swapping the direction
12 of data movement.
13 */
14 #define MINIAUDIO_IMPLEMENTATION
15 #include "../miniaudio.h"
16 
17 #include <stdio.h>
18 
19 #define DEVICE_FORMAT ma_format_f32
20 #define DEVICE_CHANNELS 1
21 #define DEVICE_SAMPLE_RATE 48000
22 
23 #define PCM_FRAME_CHUNK_SIZE 1234 /* <-- Play around with this to control your fixed sized buffer. */
24 
26 ma_pcm_rb g_rb; /* The ring buffer. */
27 
28 void data_callback_fixed(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
29 {
30  /*
31  This callback will have a guaranteed and consistent size for frameCount. In this example we just fill the output buffer with a sine wave. This
32  is where you would handle the callback just like normal, only now you can assume frameCount is a fixed size.
33  */
34  printf("frameCount=%d\n", frameCount);
35 
36  ma_waveform_read_pcm_frames(&g_sineWave, pOutput, frameCount);
37 
38  /* Unused in this example. */
39  (void)pDevice;
40  (void)pInput;
41 }
42 
43 void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
44 {
45  /*
46  This is the device's main data callback. This will handle all of the fixed sized buffer management for you and will call data_callback_fixed()
47  for you. You should do all of your normal callback stuff in data_callback_fixed().
48  */
49  ma_uint32 pcmFramesAvailableInRB;
50  ma_uint32 pcmFramesProcessed = 0;
51  ma_uint8* pRunningOutput = (ma_uint8*)pOutput;
52 
54 
55  /*
56  The first thing to do is check if there's enough data available in the ring buffer. If so we can read from it. Otherwise we need to keep filling
57  the ring buffer until there's enough, making sure we only fill the ring buffer in chunks of PCM_FRAME_CHUNK_SIZE.
58  */
59  while (pcmFramesProcessed < frameCount) { /* Keep going until we've filled the output buffer. */
60  ma_uint32 framesRemaining = frameCount - pcmFramesProcessed;
61 
62  pcmFramesAvailableInRB = ma_pcm_rb_available_read(&g_rb);
63  if (pcmFramesAvailableInRB > 0) {
64  ma_uint32 framesToRead = (framesRemaining < pcmFramesAvailableInRB) ? framesRemaining : pcmFramesAvailableInRB;
65  void* pReadBuffer;
66 
67  ma_pcm_rb_acquire_read(&g_rb, &framesToRead, &pReadBuffer);
68  {
69  memcpy(pRunningOutput, pReadBuffer, framesToRead * ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels));
70  }
71  ma_pcm_rb_commit_read(&g_rb, framesToRead, pReadBuffer);
72 
73  pRunningOutput += framesToRead * ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
74  pcmFramesProcessed += framesToRead;
75  } else {
76  /*
77  There's nothing in the buffer. Fill it with more data from the callback. We reset the buffer first so that the read and write pointers
78  are reset back to the start so we can fill the ring buffer in chunks of PCM_FRAME_CHUNK_SIZE which is what we initialized it with. Note
79  that this is not how you would want to do it in a multi-threaded environment. In this case you would want to seek the write pointer
80  forward via the producer thread and the read pointer forward via the consumer thread (this thread).
81  */
82  ma_uint32 framesToWrite = PCM_FRAME_CHUNK_SIZE;
83  void* pWriteBuffer;
84 
86  ma_pcm_rb_acquire_write(&g_rb, &framesToWrite, &pWriteBuffer);
87  {
88  MA_ASSERT(framesToWrite == PCM_FRAME_CHUNK_SIZE); /* <-- This should always work in this example because we just reset the ring buffer. */
89  data_callback_fixed(pDevice, pWriteBuffer, NULL, framesToWrite);
90  }
91  ma_pcm_rb_commit_write(&g_rb, framesToWrite, pWriteBuffer);
92  }
93  }
94 
95  /* Unused in this example. */
96  (void)pInput;
97 }
98 
99 int main(int argc, char** argv)
100 {
101  ma_waveform_config waveformConfig;
102  ma_device_config deviceConfig;
104 
106  ma_waveform_init(&waveformConfig, &g_sineWave);
107 
109 
111  deviceConfig.playback.format = DEVICE_FORMAT;
112  deviceConfig.playback.channels = DEVICE_CHANNELS;
113  deviceConfig.sampleRate = DEVICE_SAMPLE_RATE;
114  deviceConfig.dataCallback = data_callback;
115  deviceConfig.pUserData = NULL; /* <-- Set this to a pointer to the ring buffer if you don't want it in global scope. */
116 
117  if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
118  printf("Failed to open playback device.\n");
120  return -4;
121  }
122 
123  printf("Device Name: %s\n", device.playback.name);
124 
125  if (ma_device_start(&device) != MA_SUCCESS) {
126  printf("Failed to start playback device.\n");
129  return -5;
130  }
131 
132  printf("Press Enter to quit...\n");
133  getchar();
134 
137 
138  (void)argc;
139  (void)argv;
140  return 0;
141 }
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
g_rb
ma_pcm_rb g_rb
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/fixed_size_callback.c:26
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
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
DEVICE_FORMAT
#define DEVICE_FORMAT
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/fixed_size_callback.c:19
ma_pcm_rb_commit_read
ma_result ma_pcm_rb_commit_read(ma_pcm_rb *pRB, ma_uint32 sizeInFrames, void *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:36884
ma_device::format
ma_format format
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3625
ma_device_type_playback
@ ma_device_type_playback
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3012
ma_device_config::dataCallback
ma_device_callback_proc dataCallback
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3110
ma_pcm_rb_acquire_write
ma_result ma_pcm_rb_acquire_write(ma_pcm_rb *pRB, ma_uint32 *pSizeInFrames, void **ppBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:36893
device
ma_device device
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_deviceio/ma_test_deviceio.c:57
g_sineWave
ma_waveform g_sineWave
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/fixed_size_callback.c:25
ma_pcm_rb_available_read
ma_uint32 ma_pcm_rb_available_read(ma_pcm_rb *pRB)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:36949
ma_pcm_rb_commit_write
ma_result ma_pcm_rb_commit_write(ma_pcm_rb *pRB, ma_uint32 sizeInFrames, void *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:36913
ma_pcm_rb_reset
void ma_pcm_rb_reset(ma_pcm_rb *pRB)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:36855
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_ASSERT
#define MA_ASSERT(condition)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:770
DEVICE_SAMPLE_RATE
#define DEVICE_SAMPLE_RATE
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/fixed_size_callback.c:21
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
ma_waveform_type_sine
@ ma_waveform_type_sine
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5359
ma_device::name
char name[256]
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3620
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_device_config::format
ma_format format
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3128
ma_pcm_rb
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:2593
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
PCM_FRAME_CHUNK_SIZE
#define PCM_FRAME_CHUNK_SIZE
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/fixed_size_callback.c:23
ma_pcm_rb_acquire_read
ma_result ma_pcm_rb_acquire_read(ma_pcm_rb *pRB, ma_uint32 *pSizeInFrames, void **ppBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:36864
ma_pcm_rb_uninit
void ma_pcm_rb_uninit(ma_pcm_rb *pRB)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:36846
main
int main(int argc, char **argv)
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/fixed_size_callback.c:99
DEVICE_CHANNELS
#define DEVICE_CHANNELS
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/fixed_size_callback.c:20
ma_device_config::channels
ma_uint32 channels
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3129
ma_waveform_read_pcm_frames
ma_uint64 ma_waveform_read_pcm_frames(ma_waveform *pWaveform, void *pFramesOut, ma_uint64 frameCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:45751
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_config::sampleRate
ma_uint32 sampleRate
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3103
MA_SUCCESS
#define MA_SUCCESS
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1659
data_callback
void data_callback(ma_device *pDevice, void *pOutput, const void *pInput, ma_uint32 frameCount)
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/fixed_size_callback.c:43
ma_pcm_rb_init
ma_result ma_pcm_rb_init(ma_format format, ma_uint32 channels, ma_uint32 bufferSizeInFrames, void *pOptionalPreallocatedBuffer, const ma_allocation_callbacks *pAllocationCallbacks, ma_pcm_rb *pRB)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:36841
ma_device_config::playback
struct ma_device_config::@97 playback
data_callback_fixed
void data_callback_fixed(ma_device *pDevice, void *pOutput, const void *pInput, ma_uint32 frameCount)
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/fixed_size_callback.c:28
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:13:55