rhino/demo/c/dr_libs/tests/external/miniaudio/examples/simple_mixing.c
Go to the documentation of this file.
1 /*
2 Usage: simple_mixing [input file 0] [input file 1] ... [input file n]
3 Example: simple_mixing file1.wav file2.flac
4 */
5 
6 #define DR_FLAC_IMPLEMENTATION
7 #include "../extras/dr_flac.h" /* Enables FLAC decoding. */
8 #define DR_MP3_IMPLEMENTATION
9 #include "../extras/dr_mp3.h" /* Enables MP3 decoding. */
10 #define DR_WAV_IMPLEMENTATION
11 #include "../extras/dr_wav.h" /* Enables WAV decoding. */
12 
13 #define MINIAUDIO_IMPLEMENTATION
14 #include "../miniaudio.h"
15 
16 #include <stdio.h>
17 
18 /*
19 For simplicity, this example requires the device use floating point samples.
20 */
21 #define SAMPLE_FORMAT ma_format_f32
22 #define CHANNEL_COUNT 2
23 #define SAMPLE_RATE 48000
24 
28 
29 ma_event g_stopEvent; /* <-- Signaled by the audio thread, waited on by the main thread. */
30 
32 {
33  ma_uint32 iDecoder;
34  for (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
35  if (g_pDecodersAtEnd[iDecoder] == MA_FALSE) {
36  return MA_FALSE;
37  }
38  }
39 
40  return MA_TRUE;
41 }
42 
43 ma_uint32 read_and_mix_pcm_frames_f32(ma_decoder* pDecoder, float* pOutputF32, ma_uint32 frameCount)
44 {
45  /*
46  The way mixing works is that we just read into a temporary buffer, then take the contents of that buffer and mix it with the
47  contents of the output buffer by simply adding the samples together. You could also clip the samples to -1..+1, but I'm not
48  doing that in this example.
49  */
50  float temp[4096];
51  ma_uint32 tempCapInFrames = ma_countof(temp) / CHANNEL_COUNT;
52  ma_uint32 totalFramesRead = 0;
53 
54  while (totalFramesRead < frameCount) {
55  ma_uint32 iSample;
56  ma_uint32 framesReadThisIteration;
57  ma_uint32 totalFramesRemaining = frameCount - totalFramesRead;
58  ma_uint32 framesToReadThisIteration = tempCapInFrames;
59  if (framesToReadThisIteration > totalFramesRemaining) {
60  framesToReadThisIteration = totalFramesRemaining;
61  }
62 
63  framesReadThisIteration = (ma_uint32)ma_decoder_read_pcm_frames(pDecoder, temp, framesToReadThisIteration);
64  if (framesReadThisIteration == 0) {
65  break;
66  }
67 
68  /* Mix the frames together. */
69  for (iSample = 0; iSample < framesReadThisIteration*CHANNEL_COUNT; ++iSample) {
70  pOutputF32[totalFramesRead*CHANNEL_COUNT + iSample] += temp[iSample];
71  }
72 
73  totalFramesRead += framesReadThisIteration;
74 
75  if (framesReadThisIteration < framesToReadThisIteration) {
76  break; /* Reached EOF. */
77  }
78  }
79 
80  return totalFramesRead;
81 }
82 
83 void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
84 {
85  float* pOutputF32 = (float*)pOutput;
86  ma_uint32 iDecoder;
87 
88  MA_ASSERT(pDevice->playback.format == SAMPLE_FORMAT); /* <-- Important for this example. */
89 
90  for (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
91  if (!g_pDecodersAtEnd[iDecoder]) {
92  ma_uint32 framesRead = read_and_mix_pcm_frames_f32(&g_pDecoders[iDecoder], pOutputF32, frameCount);
93  if (framesRead < frameCount) {
94  g_pDecodersAtEnd[iDecoder] = MA_TRUE;
95  }
96  }
97  }
98 
99  /*
100  If at the end all of our decoders are at the end we need to stop. We cannot stop the device in the callback. Instead we need to
101  signal an event to indicate that it's stopped. The main thread will be waiting on the event, after which it will stop the device.
102  */
103  if (are_all_decoders_at_end()) {
105  }
106 
107  (void)pInput;
108 }
109 
110 int main(int argc, char** argv)
111 {
112  ma_result result;
113  ma_decoder_config decoderConfig;
114  ma_device_config deviceConfig;
116  ma_uint32 iDecoder;
117 
118  if (argc < 2) {
119  printf("No input files.\n");
120  return -1;
121  }
122 
123  g_decoderCount = argc-1;
124  g_pDecoders = (ma_decoder*)malloc(sizeof(*g_pDecoders) * g_decoderCount);
126 
127  /* In this example, all decoders need to have the same output format. */
129  for (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
130  result = ma_decoder_init_file(argv[1+iDecoder], &decoderConfig, &g_pDecoders[iDecoder]);
131  if (result != MA_SUCCESS) {
132  ma_uint32 iDecoder2;
133  for (iDecoder2 = 0; iDecoder2 < iDecoder; ++iDecoder2) {
134  ma_decoder_uninit(&g_pDecoders[iDecoder2]);
135  }
136  free(g_pDecoders);
137  free(g_pDecodersAtEnd);
138 
139  printf("Failed to load %s.\n", argv[1+iDecoder]);
140  return -3;
141  }
142  g_pDecodersAtEnd[iDecoder] = MA_FALSE;
143  }
144 
145  /* Create only a single device. The decoders will be mixed together in the callback. In this example the data format needs to be the same as the decoders. */
147  deviceConfig.playback.format = SAMPLE_FORMAT;
148  deviceConfig.playback.channels = CHANNEL_COUNT;
149  deviceConfig.sampleRate = SAMPLE_RATE;
150  deviceConfig.dataCallback = data_callback;
151  deviceConfig.pUserData = NULL;
152 
153  if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
154  for (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
155  ma_decoder_uninit(&g_pDecoders[iDecoder]);
156  }
157  free(g_pDecoders);
158  free(g_pDecodersAtEnd);
159 
160  printf("Failed to open playback device.\n");
161  return -3;
162  }
163 
164  /*
165  We can't stop in the audio thread so we instead need to use an event. We wait on this thread in the main thread, and signal it in the audio thread. This
166  needs to be done before starting the device. We need a context to initialize the event, which we can get from the device. Alternatively you can initialize
167  a context separately, but we don't need to do that for this example.
168  */
170 
171  /* Now we start playback and wait for the audio thread to tell us to stop. */
172  if (ma_device_start(&device) != MA_SUCCESS) {
174  for (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
175  ma_decoder_uninit(&g_pDecoders[iDecoder]);
176  }
177  free(g_pDecoders);
178  free(g_pDecodersAtEnd);
179 
180  printf("Failed to start playback device.\n");
181  return -4;
182  }
183 
184  printf("Waiting for playback to complete...\n");
186 
187  /* Getting here means the audio thread has signaled that the device should be stopped. */
189 
190  for (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
191  ma_decoder_uninit(&g_pDecoders[iDecoder]);
192  }
193  free(g_pDecoders);
194  free(g_pDecodersAtEnd);
195 
196  return 0;
197 }
MA_FALSE
#define MA_FALSE
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1531
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_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_bool32
ma_uint32 ma_bool32
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1529
g_pDecoders
ma_decoder * g_pDecoders
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/simple_mixing.c:26
ma_countof
#define ma_countof(x)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:776
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
main
int main(int argc, char **argv)
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/simple_mixing.c:110
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
SAMPLE_FORMAT
#define SAMPLE_FORMAT
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/simple_mixing.c:21
ma_device_config::dataCallback
ma_device_callback_proc dataCallback
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3110
are_all_decoders_at_end
ma_bool32 are_all_decoders_at_end()
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/simple_mixing.c:31
device
ma_device device
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_deviceio/ma_test_deviceio.c:57
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/simple_mixing.c:83
ma_result
int ma_result
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:1658
ma_event_wait
MA_API ma_result ma_event_wait(ma_event *pEvent)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:4898
ma_event_init
MA_API ma_result ma_event_init(ma_event *pEvent)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:4829
g_pDecodersAtEnd
ma_bool32 * g_pDecodersAtEnd
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/simple_mixing.c:27
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_event
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:2868
CHANNEL_COUNT
#define CHANNEL_COUNT
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/simple_mixing.c:22
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_decoder_read_pcm_frames
ma_uint64 ma_decoder_read_pcm_frames(ma_decoder *pDecoder, void *pFramesOut, ma_uint64 frameCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:44808
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::pContext
ma_context * pContext
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3586
read_and_mix_pcm_frames_f32
ma_uint32 read_and_mix_pcm_frames_f32(ma_decoder *pDecoder, float *pOutputF32, ma_uint32 frameCount)
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/simple_mixing.c:43
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
g_stopEvent
ma_event g_stopEvent
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/simple_mixing.c:29
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_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
SAMPLE_RATE
#define SAMPLE_RATE
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/simple_mixing.c:23
ma_device_config::playback
struct ma_device_config::@97 playback
ma_device::playback
struct ma_device::@115 playback
ma_event_signal
MA_API ma_result ma_event_signal(ma_event *pEvent)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:4913
ma_device_config::pUserData
void * pUserData
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/miniaudio.h:3112
g_decoderCount
ma_uint32 g_decoderCount
Definition: rhino/demo/c/dr_libs/tests/external/miniaudio/examples/simple_mixing.c:25


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