pvrecorder/src/miniaudio/examples/data_source_chaining.c
Go to the documentation of this file.
1 /*
2 Demonstrates one way to chain together a number of data sources so they play back seamlessly
3 without gaps.
4 
5 This example uses the chaining system built into the `ma_data_source` API. It will take every sound
6 passed onto the command line in order, and then loop back and start again. When looping a chain of
7 data sources, you need only link the last data source back to the first one.
8 
9 To play a chain of data sources, you first need to set up your chain. To set the data source that
10 should be played after another, you have two options:
11 
12  * Set a pointer to a specific data source
13  * Set a callback that will fire when the next data source needs to be retrieved
14 
15 The first option is good for simple scenarios. The second option is useful if you need to perform
16 some action when the end of a sound is reached. This example will be using both.
17 
18 When reading data from a chain, you always read from the head data source. Internally miniaudio
19 will track a pointer to the data source in the chain that is currently playing. If you don't
20 consistently read from the head data source this state will become inconsistent and things won't
21 work correctly. When using a chain, this pointer needs to be reset if you need to play the
22 chain again from the start:
23 
24  ```c
25  ma_data_source_set_current(&headDataSource, &headDataSource);
26  ma_data_source_seek_to_pcm_frame(&headDataSource, 0);
27  ```
28 
29 The code above is setting the "current" data source in the chain to the head data source, thereby
30 starting the chain from the start again. It is also seeking the head data source back to the start
31 so that playback starts from the start as expected. You do not need to seek non-head items back to
32 the start as miniaudio will do that for you internally.
33 */
34 #define MA_EXPERIMENTAL__DATA_LOOPING_AND_CHAINING
35 #define MINIAUDIO_IMPLEMENTATION
36 #include "../miniaudio.h"
37 
38 #include <stdio.h>
39 
40 /*
41 For simplicity, this example requires the device to use floating point samples.
42 */
43 #define SAMPLE_FORMAT ma_format_f32
44 #define CHANNEL_COUNT 2
45 #define SAMPLE_RATE 48000
46 
49 
51 {
52  MA_ASSERT(g_decoderCount > 0); /* <-- We check for this in main() so should never happen. */
53 
54  /*
55  This will be fired when the last item in the chain has reached the end. In this example we want
56  to loop back to the start, so we need only return a pointer back to the head.
57  */
58  return &g_pDecoders[0];
59 }
60 
61 static void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
62 {
63  /*
64  We can just read from the first decoder and miniaudio will resolve the chain for us. Note that
65  if you want to loop the chain, like we're doing in this example, you need to set the `loop`
66  parameter to false, or else only the current data source will be looped.
67  */
68  ma_data_source_read_pcm_frames(&g_pDecoders[0], pOutput, frameCount, NULL, MA_FALSE);
69 
70  /* Unused in this example. */
71  (void)pDevice;
72  (void)pInput;
73 }
74 
75 int main(int argc, char** argv)
76 {
77  ma_result result = MA_SUCCESS;
78  ma_uint32 iDecoder;
79  ma_decoder_config decoderConfig;
80  ma_device_config deviceConfig;
82 
83  if (argc < 2) {
84  printf("No input files.\n");
85  return -1;
86  }
87 
88  g_decoderCount = argc-1;
89  g_pDecoders = (ma_decoder*)malloc(sizeof(*g_pDecoders) * g_decoderCount);
90 
91  /* In this example, all decoders need to have the same output format. */
93  for (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
94  result = ma_decoder_init_file(argv[1+iDecoder], &decoderConfig, &g_pDecoders[iDecoder]);
95  if (result != MA_SUCCESS) {
96  ma_uint32 iDecoder2;
97  for (iDecoder2 = 0; iDecoder2 < iDecoder; ++iDecoder2) {
98  ma_decoder_uninit(&g_pDecoders[iDecoder2]);
99  }
100  free(g_pDecoders);
101 
102  printf("Failed to load %s.\n", argv[1+iDecoder]);
103  return -1;
104  }
105  }
106 
107  /*
108  We're going to set up our decoders to run one after the other, but then have the last one loop back
109  to the first one. For demonstration purposes we're going to use the callback method for the last
110  data source.
111  */
112  for (iDecoder = 0; iDecoder < g_decoderCount-1; iDecoder += 1) {
113  ma_data_source_set_next(&g_pDecoders[iDecoder], &g_pDecoders[iDecoder+1]);
114  }
115 
116  /*
117  For the last data source we'll loop back to the start, but for demonstration purposes we'll use a
118  callback to determine the next data source in the chain.
119  */
120  ma_data_source_set_next_callback(&g_pDecoders[g_decoderCount-1], next_callback_tail);
121 
122 
123  /*
124  The data source chain has been established so now we can get the device up and running so we
125  can listen to it.
126  */
128  deviceConfig.playback.format = SAMPLE_FORMAT;
129  deviceConfig.playback.channels = CHANNEL_COUNT;
130  deviceConfig.sampleRate = SAMPLE_RATE;
131  deviceConfig.dataCallback = data_callback;
132  deviceConfig.pUserData = NULL;
133 
134  if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
135  printf("Failed to open playback device.\n");
136  result = -1;
137  goto done_decoders;
138  }
139 
140  if (ma_device_start(&device) != MA_SUCCESS) {
141  printf("Failed to start playback device.\n");
142  result = -1;
143  goto done;
144  }
145 
146  printf("Press Enter to quit...");
147  getchar();
148 
149 done:
151 
152 done_decoders:
153  for (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
154  ma_decoder_uninit(&g_pDecoders[iDecoder]);
155  }
156  free(g_pDecoders);
157 
158  return 0;
159 }
MA_FALSE
#define MA_FALSE
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1531
g_pDecoders
ma_decoder * g_pDecoders
Definition: pvrecorder/src/miniaudio/examples/data_source_chaining.c:48
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
data_callback
static void data_callback(ma_device *pDevice, void *pOutput, const void *pInput, ma_uint32 frameCount)
Definition: pvrecorder/src/miniaudio/examples/data_source_chaining.c:61
ma_decoder_uninit
ma_result ma_decoder_uninit(ma_decoder *pDecoder)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:44739
ma_decoder_config
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5170
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_decoder_config_init
ma_decoder_config ma_decoder_config_init(ma_format outputFormat, ma_uint32 outputChannels, ma_uint32 outputSampleRate)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:40646
g_decoderCount
ma_uint32 g_decoderCount
Definition: pvrecorder/src/miniaudio/examples/data_source_chaining.c:47
next_callback_tail
static ma_data_source * next_callback_tail(ma_data_source *pDataSource)
Definition: pvrecorder/src/miniaudio/examples/data_source_chaining.c:50
ma_data_source
void ma_data_source
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.h:4500
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
device
ma_device device
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_deviceio/ma_test_deviceio.c:57
main
int main(int argc, char **argv)
Definition: pvrecorder/src/miniaudio/examples/data_source_chaining.c:75
CHANNEL_COUNT
#define CHANNEL_COUNT
Definition: pvrecorder/src/miniaudio/examples/data_source_chaining.c:44
ma_result
int ma_result
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1658
ma_decoder
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:5193
MA_ASSERT
#define MA_ASSERT(condition)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:770
ma_uint32
uint32_t ma_uint32
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1503
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_device_config::channels
ma_uint32 channels
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3129
ma_decoder_init_file
ma_result ma_decoder_init_file(const char *pFilePath, const ma_decoder_config *pConfig, ma_decoder *pDecoder)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:44687
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
SAMPLE_RATE
#define SAMPLE_RATE
Definition: pvrecorder/src/miniaudio/examples/data_source_chaining.c:45
SAMPLE_FORMAT
#define SAMPLE_FORMAT
Definition: pvrecorder/src/miniaudio/examples/data_source_chaining.c:43
ma_device_config::playback
struct ma_device_config::@97 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:48