pvrecorder/src/miniaudio/examples/fixed_size_callback.c
Go to the documentation of this file.
1 /*
2 Shows one way to implement a data callback that is called with a fixed frame count.
3 
4 miniaudio does not have built-in support for firing the data callback with fixed sized buffers. In order to support
5 this you need to implement a layer that sits on top of the normal data callback. This example demonstrates one way of
6 doing this.
7 
8 This example uses a ring buffer to act as the intermediary buffer between the low-level device callback and the fixed
9 sized callback. You do not need to use a ring buffer here, but it's a good opportunity to demonstrate how to use
10 miniaudio's ring buffer API. The ring buffer in this example is in global scope for simplicity, but you can pass it
11 around as user data for the device (device.pUserData).
12 
13 This example only works for output devices, but can be implemented for input devices by simply swapping the direction
14 of data movement.
15 */
16 #define MINIAUDIO_IMPLEMENTATION
17 #include "../miniaudio.h"
18 
19 #include <stdio.h>
20 
21 #define DEVICE_FORMAT ma_format_f32
22 #define DEVICE_CHANNELS 1
23 #define DEVICE_SAMPLE_RATE 48000
24 
25 #define PCM_FRAME_CHUNK_SIZE 1234 /* <-- Play around with this to control your fixed sized buffer. */
26 
28 ma_pcm_rb g_rb; /* The ring buffer. */
29 
30 void data_callback_fixed(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
31 {
32  /*
33  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
34  is where you would handle the callback just like normal, only now you can assume frameCount is a fixed size.
35  */
36  printf("frameCount=%d\n", frameCount);
37 
38  ma_waveform_read_pcm_frames(&g_sineWave, pOutput, frameCount);
39 
40  /* Unused in this example. */
41  (void)pDevice;
42  (void)pInput;
43 }
44 
45 void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
46 {
47  /*
48  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()
49  for you. You should do all of your normal callback stuff in data_callback_fixed().
50  */
51  ma_uint32 pcmFramesAvailableInRB;
52  ma_uint32 pcmFramesProcessed = 0;
53  ma_uint8* pRunningOutput = (ma_uint8*)pOutput;
54 
56 
57  /*
58  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
59  the ring buffer until there's enough, making sure we only fill the ring buffer in chunks of PCM_FRAME_CHUNK_SIZE.
60  */
61  while (pcmFramesProcessed < frameCount) { /* Keep going until we've filled the output buffer. */
62  ma_uint32 framesRemaining = frameCount - pcmFramesProcessed;
63 
64  pcmFramesAvailableInRB = ma_pcm_rb_available_read(&g_rb);
65  if (pcmFramesAvailableInRB > 0) {
66  ma_uint32 framesToRead = (framesRemaining < pcmFramesAvailableInRB) ? framesRemaining : pcmFramesAvailableInRB;
67  void* pReadBuffer;
68 
69  ma_pcm_rb_acquire_read(&g_rb, &framesToRead, &pReadBuffer);
70  {
71  memcpy(pRunningOutput, pReadBuffer, framesToRead * ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels));
72  }
73  ma_pcm_rb_commit_read(&g_rb, framesToRead, pReadBuffer);
74 
75  pRunningOutput += framesToRead * ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
76  pcmFramesProcessed += framesToRead;
77  } else {
78  /*
79  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
80  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
81  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
82  forward via the producer thread and the read pointer forward via the consumer thread (this thread).
83  */
84  ma_uint32 framesToWrite = PCM_FRAME_CHUNK_SIZE;
85  void* pWriteBuffer;
86 
88  ma_pcm_rb_acquire_write(&g_rb, &framesToWrite, &pWriteBuffer);
89  {
90  MA_ASSERT(framesToWrite == PCM_FRAME_CHUNK_SIZE); /* <-- This should always work in this example because we just reset the ring buffer. */
91  data_callback_fixed(pDevice, pWriteBuffer, NULL, framesToWrite);
92  }
93  ma_pcm_rb_commit_write(&g_rb, framesToWrite, pWriteBuffer);
94  }
95  }
96 
97  /* Unused in this example. */
98  (void)pInput;
99 }
100 
101 int main(int argc, char** argv)
102 {
103  ma_waveform_config waveformConfig;
104  ma_device_config deviceConfig;
106 
108  ma_waveform_init(&waveformConfig, &g_sineWave);
109 
111 
113  deviceConfig.playback.format = DEVICE_FORMAT;
114  deviceConfig.playback.channels = DEVICE_CHANNELS;
115  deviceConfig.sampleRate = DEVICE_SAMPLE_RATE;
116  deviceConfig.dataCallback = data_callback;
117  deviceConfig.pUserData = NULL; /* <-- Set this to a pointer to the ring buffer if you don't want it in global scope. */
118 
119  if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
120  printf("Failed to open playback device.\n");
122  return -4;
123  }
124 
125  printf("Device Name: %s\n", device.playback.name);
126 
127  if (ma_device_start(&device) != MA_SUCCESS) {
128  printf("Failed to start playback device.\n");
131  return -5;
132  }
133 
134  printf("Press Enter to quit...\n");
135  getchar();
136 
139 
140  (void)argc;
141  (void)argv;
142  return 0;
143 }
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_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
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
DEVICE_SAMPLE_RATE
#define DEVICE_SAMPLE_RATE
Definition: pvrecorder/src/miniaudio/examples/fixed_size_callback.c:23
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
data_callback
void data_callback(ma_device *pDevice, void *pOutput, const void *pInput, ma_uint32 frameCount)
Definition: pvrecorder/src/miniaudio/examples/fixed_size_callback.c:45
device
ma_device device
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_deviceio/ma_test_deviceio.c:57
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
DEVICE_CHANNELS
#define DEVICE_CHANNELS
Definition: pvrecorder/src/miniaudio/examples/fixed_size_callback.c:22
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
g_rb
ma_pcm_rb g_rb
Definition: pvrecorder/src/miniaudio/examples/fixed_size_callback.c:28
MA_ASSERT
#define MA_ASSERT(condition)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:770
g_sineWave
ma_waveform g_sineWave
Definition: pvrecorder/src/miniaudio/examples/fixed_size_callback.c:27
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
DEVICE_FORMAT
#define DEVICE_FORMAT
Definition: pvrecorder/src/miniaudio/examples/fixed_size_callback.c:21
PCM_FRAME_CHUNK_SIZE
#define PCM_FRAME_CHUNK_SIZE
Definition: pvrecorder/src/miniaudio/examples/fixed_size_callback.c:25
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
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
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
main
int main(int argc, char **argv)
Definition: pvrecorder/src/miniaudio/examples/fixed_size_callback.c:101
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
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
data_callback_fixed
void data_callback_fixed(ma_device *pDevice, void *pOutput, const void *pInput, ma_uint32 frameCount)
Definition: pvrecorder/src/miniaudio/examples/fixed_size_callback.c:30
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:13:55