Add syntax highlighting to documentation.

This commit is contained in:
David Reid
2020-07-16 21:32:01 +10:00
parent aba471bbe9
commit ba57831c18
10 changed files with 469 additions and 469 deletions
+53 -53
View File
@@ -262,58 +262,58 @@ around as user data for the device (device.pUserData).
This example only works for output devices, but can be implemented for input devices by simply swapping the direction
of data movement.</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
#define MINIAUDIO_IMPLEMENTATION
#include &quot;../miniaudio.h&quot;
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
<span style="color:#666666">#include</span> <span style="color:#cc3300">&quot;../miniaudio.h&quot;</span>
#include &lt;stdio.h&gt;
<span style="color:#666666">#include</span> <span style="color:#cc3300">&lt;stdio.h&gt;</span>
#define DEVICE_FORMAT ma_format_f32
#define DEVICE_CHANNELS 1
#define DEVICE_SAMPLE_RATE 48000
<span style="color:#666666">#define</span> DEVICE_FORMAT ma_format_f32
<span style="color:#666666">#define</span> DEVICE_CHANNELS 1
<span style="color:#666666">#define</span> DEVICE_SAMPLE_RATE 48000
#define PCM_FRAME_CHUNK_SIZE 1234 /* &lt;-- Play around with this to control your fixed sized buffer. */
<span style="color:#666666">#define</span> PCM_FRAME_CHUNK_SIZE 1234 <span style="color:#009900">/* &lt;-- Play around with this to control your fixed sized buffer. */</span>
ma_waveform g_sineWave;
ma_pcm_rb g_rb; /* The ring buffer. */
<span style="color:#0099cc">ma_waveform</span> g_sineWave;
<span style="color:#0099cc">ma_pcm_rb</span> g_rb; <span style="color:#009900">/* The ring buffer. */</span>
void data_callback_fixed(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
<span style="color:#0033ff">void</span> data_callback_fixed(<span style="color:#0099cc">ma_device</span>* pDevice, <span style="color:#0033ff">void</span>* pOutput, <span style="color:#0033ff">const</span> <span style="color:#0033ff">void</span>* pInput, <span style="color:#0099cc">ma_uint32</span> frameCount)
{
/*
<span style="color:#009900">/*
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
is where you would handle the callback just like normal, only now you can assume frameCount is a fixed size.
*/
printf(&quot;frameCount=%d\n&quot;, frameCount);
*/</span>
printf(<span style="color:#cc3300">&quot;frameCount=%d\n&quot;</span>, frameCount);
ma_waveform_read_pcm_frames(&amp;g_sineWave, pOutput, frameCount);
/* Unused in this example. */
(void)pDevice;
(void)pInput;
<span style="color:#009900">/* Unused in this example. */</span>
(<span style="color:#0033ff">void</span>)pDevice;
(<span style="color:#0033ff">void</span>)pInput;
}
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
<span style="color:#0033ff">void</span> data_callback(<span style="color:#0099cc">ma_device</span>* pDevice, <span style="color:#0033ff">void</span>* pOutput, <span style="color:#0033ff">const</span> <span style="color:#0033ff">void</span>* pInput, <span style="color:#0099cc">ma_uint32</span> frameCount)
{
/*
<span style="color:#009900">/*
This is the device&#39;s main data callback. This will handle all of the fixed sized buffer management for you and will call data_callback_fixed()
for you. You should do all of your normal callback stuff in data_callback_fixed().
*/
ma_uint32 pcmFramesAvailableInRB;
ma_uint32 pcmFramesProcessed = 0;
ma_uint8* pRunningOutput = (ma_uint8*)pOutput;
*/</span>
<span style="color:#0099cc">ma_uint32</span> pcmFramesAvailableInRB;
<span style="color:#0099cc">ma_uint32</span> pcmFramesProcessed = 0;
<span style="color:#0099cc">ma_uint8</span>* pRunningOutput = (<span style="color:#0099cc">ma_uint8</span>*)pOutput;
MA_ASSERT(pDevice-&gt;playback.channels == DEVICE_CHANNELS);
/*
<span style="color:#009900">/*
The first thing to do is check if there&#39;s enough data available in the ring buffer. If so we can read from it. Otherwise we need to keep filling
the ring buffer until there&#39;s enough, making sure we only fill the ring buffer in chunks of PCM_FRAME_CHUNK_SIZE.
*/
while (pcmFramesProcessed &lt; frameCount) { /* Keep going until we&#39;ve filled the output buffer. */
ma_uint32 framesRemaining = frameCount - pcmFramesProcessed;
*/</span>
<span style="color:#0033ff">while</span> (pcmFramesProcessed &lt; frameCount) { <span style="color:#009900">/* Keep going until we&#39;ve filled the output buffer. */</span>
<span style="color:#0099cc">ma_uint32</span> framesRemaining = frameCount - pcmFramesProcessed;
pcmFramesAvailableInRB = ma_pcm_rb_available_read(&amp;g_rb);
if (pcmFramesAvailableInRB &gt; 0) {
ma_uint32 framesToRead = (framesRemaining &lt; pcmFramesAvailableInRB) ? framesRemaining : pcmFramesAvailableInRB;
void* pReadBuffer;
<span style="color:#0033ff">if</span> (pcmFramesAvailableInRB &gt; 0) {
<span style="color:#0099cc">ma_uint32</span> framesToRead = (framesRemaining &lt; pcmFramesAvailableInRB) ? framesRemaining : pcmFramesAvailableInRB;
<span style="color:#0033ff">void</span>* pReadBuffer;
ma_pcm_rb_acquire_read(&amp;g_rb, &amp;framesToRead, &amp;pReadBuffer);
{
@@ -323,35 +323,35 @@ void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uin
pRunningOutput += framesToRead * ma_get_bytes_per_frame(pDevice-&gt;playback.format, pDevice-&gt;playback.channels);
pcmFramesProcessed += framesToRead;
} else {
/*
} <span style="color:#0033ff">else</span> {
<span style="color:#009900">/*
There&#39;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
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
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
forward via the producer thread and the read pointer forward via the consumer thread (this thread).
*/
ma_uint32 framesToWrite = PCM_FRAME_CHUNK_SIZE;
void* pWriteBuffer;
*/</span>
<span style="color:#0099cc">ma_uint32</span> framesToWrite = PCM_FRAME_CHUNK_SIZE;
<span style="color:#0033ff">void</span>* pWriteBuffer;
ma_pcm_rb_reset(&amp;g_rb);
ma_pcm_rb_acquire_write(&amp;g_rb, &amp;framesToWrite, &amp;pWriteBuffer);
{
MA_ASSERT(framesToWrite == PCM_FRAME_CHUNK_SIZE); /* &lt;-- This should always work in this example because we just reset the ring buffer. */
MA_ASSERT(framesToWrite == PCM_FRAME_CHUNK_SIZE); <span style="color:#009900">/* &lt;-- This should always work in this example because we just reset the ring buffer. */</span>
data_callback_fixed(pDevice, pWriteBuffer, NULL, framesToWrite);
}
ma_pcm_rb_commit_write(&amp;g_rb, framesToWrite, pWriteBuffer);
}
}
/* Unused in this example. */
(void)pInput;
<span style="color:#009900">/* Unused in this example. */</span>
(<span style="color:#0033ff">void</span>)pInput;
}
int main(int argc, char** argv)
<span style="color:#0033ff">int</span> main(<span style="color:#0033ff">int</span> argc, <span style="color:#0033ff">char</span>** argv)
{
ma_waveform_config waveformConfig;
ma_device_config deviceConfig;
ma_device device;
<span style="color:#0099cc">ma_waveform_config</span> waveformConfig;
<span style="color:#0099cc">ma_device_config</span> deviceConfig;
<span style="color:#0099cc">ma_device</span> device;
waveformConfig = ma_waveform_config_init(DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, ma_waveform_type_sine, 0.1, 220);
ma_waveform_init(&amp;waveformConfig, &amp;g_sineWave);
@@ -363,32 +363,32 @@ int main(int argc, char** argv)
deviceConfig.playback.channels = DEVICE_CHANNELS;
deviceConfig.sampleRate = DEVICE_SAMPLE_RATE;
deviceConfig.dataCallback = data_callback;
deviceConfig.pUserData = NULL; /* &lt;-- Set this to a pointer to the ring buffer if you don&#39;t want it in global scope. */
deviceConfig.pUserData = NULL; <span style="color:#009900">/* &lt;-- Set this to a pointer to the ring buffer if you don&#39;t want it in global scope. */</span>
if (ma_device_init(NULL, &amp;deviceConfig, &amp;device) != MA_SUCCESS) {
printf(&quot;Failed to open playback device.\n&quot;);
<span style="color:#0033ff">if</span> (ma_device_init(NULL, &amp;deviceConfig, &amp;device) != MA_SUCCESS) {
printf(<span style="color:#cc3300">&quot;Failed to open playback device.\n&quot;</span>);
ma_pcm_rb_uninit(&amp;g_rb);
return -4;
<span style="color:#0033ff">return</span> -4;
}
printf(&quot;Device Name: %s\n&quot;, device.playback.name);
printf(<span style="color:#cc3300">&quot;Device Name: %s\n&quot;</span>, device.playback.name);
if (ma_device_start(&amp;device) != MA_SUCCESS) {
printf(&quot;Failed to start playback device.\n&quot;);
<span style="color:#0033ff">if</span> (ma_device_start(&amp;device) != MA_SUCCESS) {
printf(<span style="color:#cc3300">&quot;Failed to start playback device.\n&quot;</span>);
ma_pcm_rb_uninit(&amp;g_rb);
ma_device_uninit(&amp;device);
return -5;
<span style="color:#0033ff">return</span> -5;
}
printf(&quot;Press Enter to quit...\n&quot;);
printf(<span style="color:#cc3300">&quot;Press Enter to quit...\n&quot;</span>);
getchar();
ma_device_uninit(&amp;device);
ma_pcm_rb_uninit(&amp;g_rb);
(void)argc;
(void)argv;
return 0;
(<span style="color:#0033ff">void</span>)argc;
(<span style="color:#0033ff">void</span>)argv;
<span style="color:#0033ff">return</span> 0;
}
</pre></div></td>
</tr></table>
+27 -27
View File
@@ -255,40 +255,40 @@ Capturing works in a very similar way to playback. The only difference is the di
the application sending data to the device, the device will send data to the application. This example just writes the
data received by the microphone straight to a WAV file.</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
#define MINIAUDIO_IMPLEMENTATION
#include &quot;../miniaudio.h&quot;
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
<span style="color:#666666">#include</span> <span style="color:#cc3300">&quot;../miniaudio.h&quot;</span>
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
<span style="color:#666666">#include</span> <span style="color:#cc3300">&lt;stdlib.h&gt;</span>
<span style="color:#666666">#include</span> <span style="color:#cc3300">&lt;stdio.h&gt;</span>
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
<span style="color:#0033ff">void</span> data_callback(<span style="color:#0099cc">ma_device</span>* pDevice, <span style="color:#0033ff">void</span>* pOutput, <span style="color:#0033ff">const</span> <span style="color:#0033ff">void</span>* pInput, <span style="color:#0099cc">ma_uint32</span> frameCount)
{
ma_encoder* pEncoder = (ma_encoder*)pDevice-&gt;pUserData;
<span style="color:#0099cc">ma_encoder</span>* pEncoder = (<span style="color:#0099cc">ma_encoder</span>*)pDevice-&gt;pUserData;
MA_ASSERT(pEncoder != NULL);
ma_encoder_write_pcm_frames(pEncoder, pInput, frameCount);
(void)pOutput;
(<span style="color:#0033ff">void</span>)pOutput;
}
int main(int argc, char** argv)
<span style="color:#0033ff">int</span> main(<span style="color:#0033ff">int</span> argc, <span style="color:#0033ff">char</span>** argv)
{
ma_result result;
ma_encoder_config encoderConfig;
ma_encoder encoder;
ma_device_config deviceConfig;
ma_device device;
<span style="color:#0099cc">ma_result</span> result;
<span style="color:#0099cc">ma_encoder_config</span> encoderConfig;
<span style="color:#0099cc">ma_encoder</span> encoder;
<span style="color:#0099cc">ma_device_config</span> deviceConfig;
<span style="color:#0099cc">ma_device</span> device;
if (argc &lt; 2) {
printf(&quot;No input file.\n&quot;);
return -1;
<span style="color:#0033ff">if</span> (argc &lt; 2) {
printf(<span style="color:#cc3300">&quot;No input file.\n&quot;</span>);
<span style="color:#0033ff">return</span> -1;
}
encoderConfig = ma_encoder_config_init(ma_resource_format_wav, ma_format_f32, 2, 44100);
if (ma_encoder_init_file(argv[1], &amp;encoderConfig, &amp;encoder) != MA_SUCCESS) {
printf(&quot;Failed to initialize output file.\n&quot;);
return -1;
<span style="color:#0033ff">if</span> (ma_encoder_init_file(argv[1], &amp;encoderConfig, &amp;encoder) != MA_SUCCESS) {
printf(<span style="color:#cc3300">&quot;Failed to initialize output file.\n&quot;</span>);
<span style="color:#0033ff">return</span> -1;
}
deviceConfig = ma_device_config_init(ma_device_type_capture);
@@ -299,25 +299,25 @@ int main(int argc, char** argv)
deviceConfig.pUserData = &amp;encoder;
result = ma_device_init(NULL, &amp;deviceConfig, &amp;device);
if (result != MA_SUCCESS) {
printf(&quot;Failed to initialize capture device.\n&quot;);
return -2;
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
printf(<span style="color:#cc3300">&quot;Failed to initialize capture device.\n&quot;</span>);
<span style="color:#0033ff">return</span> -2;
}
result = ma_device_start(&amp;device);
if (result != MA_SUCCESS) {
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
ma_device_uninit(&amp;device);
printf(&quot;Failed to start device.\n&quot;);
return -3;
printf(<span style="color:#cc3300">&quot;Failed to start device.\n&quot;</span>);
<span style="color:#0033ff">return</span> -3;
}
printf(&quot;Press Enter to stop recording...\n&quot;);
printf(<span style="color:#cc3300">&quot;Press Enter to stop recording...\n&quot;</span>);
getchar();
ma_device_uninit(&amp;device);
ma_encoder_uninit(&amp;encoder);
return 0;
<span style="color:#0033ff">return</span> 0;
}
</pre></div></td>
</tr></table>
+23 -23
View File
@@ -257,31 +257,31 @@ glitching which the backend may not be able to recover from. For this reason, mi
sample rate for both capture and playback. If internally the native sample rates differ, miniaudio will perform the
sample rate conversion for you automatically.</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
#define MINIAUDIO_IMPLEMENTATION
#include &quot;../miniaudio.h&quot;
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
<span style="color:#666666">#include</span> <span style="color:#cc3300">&quot;../miniaudio.h&quot;</span>
#include &lt;stdio.h&gt;
<span style="color:#666666">#include</span> <span style="color:#cc3300">&lt;stdio.h&gt;</span>
#ifdef __EMSCRIPTEN__
void main_loop__em()
<span style="color:#666666">#ifdef</span> __EMSCRIPTEN__
<span style="color:#0033ff">void</span> main_loop__em()
{
}
#endif
<span style="color:#666666">#endif</span>
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
<span style="color:#0033ff">void</span> data_callback(<span style="color:#0099cc">ma_device</span>* pDevice, <span style="color:#0033ff">void</span>* pOutput, <span style="color:#0033ff">const</span> <span style="color:#0033ff">void</span>* pInput, <span style="color:#0099cc">ma_uint32</span> frameCount)
{
MA_ASSERT(pDevice-&gt;capture.format == pDevice-&gt;playback.format);
MA_ASSERT(pDevice-&gt;capture.channels == pDevice-&gt;playback.channels);
/* In this example the format and channel count are the same for both input and output which means we can just memcpy(). */
<span style="color:#009900">/* In this example the format and channel count are the same for both input and output which means we can just memcpy(). */</span>
MA_COPY_MEMORY(pOutput, pInput, frameCount * ma_get_bytes_per_frame(pDevice-&gt;capture.format, pDevice-&gt;capture.channels));
}
int main(int argc, char** argv)
<span style="color:#0033ff">int</span> main(<span style="color:#0033ff">int</span> argc, <span style="color:#0033ff">char</span>** argv)
{
ma_result result;
ma_device_config deviceConfig;
ma_device device;
<span style="color:#0099cc">ma_result</span> result;
<span style="color:#0099cc">ma_device_config</span> deviceConfig;
<span style="color:#0099cc">ma_device</span> device;
deviceConfig = ma_device_config_init(ma_device_type_duplex);
deviceConfig.capture.pDeviceID = NULL;
@@ -293,28 +293,28 @@ int main(int argc, char** argv)
deviceConfig.playback.channels = 2;
deviceConfig.dataCallback = data_callback;
result = ma_device_init(NULL, &amp;deviceConfig, &amp;device);
if (result != MA_SUCCESS) {
return result;
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#0033ff">return</span> result;
}
#ifdef __EMSCRIPTEN__
<span style="color:#666666">#ifdef</span> __EMSCRIPTEN__
getchar();
#endif
<span style="color:#666666">#endif</span>
ma_device_start(&amp;device);
#ifdef __EMSCRIPTEN__
<span style="color:#666666">#ifdef</span> __EMSCRIPTEN__
emscripten_set_main_loop(main_loop__em, 0, 1);
#else
printf(&quot;Press Enter to quit...\n&quot;);
<span style="color:#666666">#else</span>
printf(<span style="color:#cc3300">&quot;Press Enter to quit...\n&quot;</span>);
getchar();
#endif
<span style="color:#666666">#endif</span>
ma_device_uninit(&amp;device);
(void)argc;
(void)argv;
return 0;
(<span style="color:#0033ff">void</span>)argc;
(<span style="color:#0033ff">void</span>)argv;
<span style="color:#0033ff">return</span> 0;
}
</pre></div></td>
</tr></table>
+27 -27
View File
@@ -254,50 +254,50 @@ context sits above a device. You can have many devices to one context.
If you use device enumeration, you should explicitly specify the same context you used for enumeration in the call to
<span style="font-family:monospace;">ma_device_init()</span> when you initialize your devices.</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
#define MINIAUDIO_IMPLEMENTATION
#include &quot;../miniaudio.h&quot;
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
<span style="color:#666666">#include</span> <span style="color:#cc3300">&quot;../miniaudio.h&quot;</span>
#include &lt;stdio.h&gt;
<span style="color:#666666">#include</span> <span style="color:#cc3300">&lt;stdio.h&gt;</span>
int main(int argc, char** argv)
<span style="color:#0033ff">int</span> main(<span style="color:#0033ff">int</span> argc, <span style="color:#0033ff">char</span>** argv)
{
ma_result result;
ma_context context;
ma_device_info* pPlaybackDeviceInfos;
ma_uint32 playbackDeviceCount;
ma_device_info* pCaptureDeviceInfos;
ma_uint32 captureDeviceCount;
ma_uint32 iDevice;
<span style="color:#0099cc">ma_result</span> result;
<span style="color:#0099cc">ma_context</span> context;
<span style="color:#0099cc">ma_device_info</span>* pPlaybackDeviceInfos;
<span style="color:#0099cc">ma_uint32</span> playbackDeviceCount;
<span style="color:#0099cc">ma_device_info</span>* pCaptureDeviceInfos;
<span style="color:#0099cc">ma_uint32</span> captureDeviceCount;
<span style="color:#0099cc">ma_uint32</span> iDevice;
if (ma_context_init(NULL, 0, NULL, &amp;context) != MA_SUCCESS) {
printf(&quot;Failed to initialize context.\n&quot;);
return -2;
<span style="color:#0033ff">if</span> (ma_context_init(NULL, 0, NULL, &amp;context) != MA_SUCCESS) {
printf(<span style="color:#cc3300">&quot;Failed to initialize context.\n&quot;</span>);
<span style="color:#0033ff">return</span> -2;
}
result = ma_context_get_devices(&amp;context, &amp;pPlaybackDeviceInfos, &amp;playbackDeviceCount, &amp;pCaptureDeviceInfos, &amp;captureDeviceCount);
if (result != MA_SUCCESS) {
printf(&quot;Failed to retrieve device information.\n&quot;);
return -3;
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
printf(<span style="color:#cc3300">&quot;Failed to retrieve device information.\n&quot;</span>);
<span style="color:#0033ff">return</span> -3;
}
printf(&quot;Playback Devices\n&quot;);
for (iDevice = 0; iDevice &lt; playbackDeviceCount; ++iDevice) {
printf(&quot; %u: %s\n&quot;, iDevice, pPlaybackDeviceInfos[iDevice].name);
printf(<span style="color:#cc3300">&quot;Playback Devices\n&quot;</span>);
<span style="color:#0033ff">for</span> (iDevice = 0; iDevice &lt; playbackDeviceCount; ++iDevice) {
printf(<span style="color:#cc3300">&quot; %u: %s\n&quot;</span>, iDevice, pPlaybackDeviceInfos[iDevice].name);
}
printf(&quot;\n&quot;);
printf(<span style="color:#cc3300">&quot;\n&quot;</span>);
printf(&quot;Capture Devices\n&quot;);
for (iDevice = 0; iDevice &lt; captureDeviceCount; ++iDevice) {
printf(&quot; %u: %s\n&quot;, iDevice, pCaptureDeviceInfos[iDevice].name);
printf(<span style="color:#cc3300">&quot;Capture Devices\n&quot;</span>);
<span style="color:#0033ff">for</span> (iDevice = 0; iDevice &lt; captureDeviceCount; ++iDevice) {
printf(<span style="color:#cc3300">&quot; %u: %s\n&quot;</span>, iDevice, pCaptureDeviceInfos[iDevice].name);
}
ma_context_uninit(&amp;context);
(void)argc;
(void)argv;
return 0;
(<span style="color:#0033ff">void</span>)argc;
(<span style="color:#0033ff">void</span>)argv;
<span style="color:#0033ff">return</span> 0;
}
</pre></div></td>
</tr></table>
+30 -30
View File
@@ -259,75 +259,75 @@ used indirectly with PulseAudio by choosing the appropriate loopback device afte
To use loopback mode you just need to set the device type to ma_device_type_loopback and set the capture device config
properties. The output buffer in the callback will be null whereas the input buffer will be valid.</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
#define MINIAUDIO_IMPLEMENTATION
#include &quot;../miniaudio.h&quot;
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
<span style="color:#666666">#include</span> <span style="color:#cc3300">&quot;../miniaudio.h&quot;</span>
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
<span style="color:#666666">#include</span> <span style="color:#cc3300">&lt;stdlib.h&gt;</span>
<span style="color:#666666">#include</span> <span style="color:#cc3300">&lt;stdio.h&gt;</span>
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
<span style="color:#0033ff">void</span> data_callback(<span style="color:#0099cc">ma_device</span>* pDevice, <span style="color:#0033ff">void</span>* pOutput, <span style="color:#0033ff">const</span> <span style="color:#0033ff">void</span>* pInput, <span style="color:#0099cc">ma_uint32</span> frameCount)
{
ma_encoder* pEncoder = (ma_encoder*)pDevice-&gt;pUserData;
<span style="color:#0099cc">ma_encoder</span>* pEncoder = (<span style="color:#0099cc">ma_encoder</span>*)pDevice-&gt;pUserData;
MA_ASSERT(pEncoder != NULL);
ma_encoder_write_pcm_frames(pEncoder, pInput, frameCount);
(void)pOutput;
(<span style="color:#0033ff">void</span>)pOutput;
}
int main(int argc, char** argv)
<span style="color:#0033ff">int</span> main(<span style="color:#0033ff">int</span> argc, <span style="color:#0033ff">char</span>** argv)
{
ma_result result;
ma_encoder_config encoderConfig;
ma_encoder encoder;
ma_device_config deviceConfig;
ma_device device;
<span style="color:#0099cc">ma_result</span> result;
<span style="color:#0099cc">ma_encoder_config</span> encoderConfig;
<span style="color:#0099cc">ma_encoder</span> encoder;
<span style="color:#0099cc">ma_device_config</span> deviceConfig;
<span style="color:#0099cc">ma_device</span> device;
/* Loopback mode is currently only supported on WASAPI. */
<span style="color:#009900">/* Loopback mode is currently only supported on WASAPI. */</span>
ma_backend backends[] = {
ma_backend_wasapi
};
if (argc &lt; 2) {
printf(&quot;No input file.\n&quot;);
return -1;
<span style="color:#0033ff">if</span> (argc &lt; 2) {
printf(<span style="color:#cc3300">&quot;No input file.\n&quot;</span>);
<span style="color:#0033ff">return</span> -1;
}
encoderConfig = ma_encoder_config_init(ma_resource_format_wav, ma_format_f32, 2, 44100);
if (ma_encoder_init_file(argv[1], &amp;encoderConfig, &amp;encoder) != MA_SUCCESS) {
printf(&quot;Failed to initialize output file.\n&quot;);
return -1;
<span style="color:#0033ff">if</span> (ma_encoder_init_file(argv[1], &amp;encoderConfig, &amp;encoder) != MA_SUCCESS) {
printf(<span style="color:#cc3300">&quot;Failed to initialize output file.\n&quot;</span>);
<span style="color:#0033ff">return</span> -1;
}
deviceConfig = ma_device_config_init(ma_device_type_loopback);
deviceConfig.capture.pDeviceID = NULL; /* Use default device for this example. Set this to the ID of a _playback_ device if you want to capture from a specific device. */
deviceConfig.capture.pDeviceID = NULL; <span style="color:#009900">/* Use default device for this example. Set this to the ID of a _playback_ device if you want to capture from a specific device. */</span>
deviceConfig.capture.format = encoder.config.format;
deviceConfig.capture.channels = encoder.config.channels;
deviceConfig.sampleRate = encoder.config.sampleRate;
deviceConfig.dataCallback = data_callback;
deviceConfig.pUserData = &amp;encoder;
result = ma_device_init_ex(backends, sizeof(backends)/sizeof(backends[0]), NULL, &amp;deviceConfig, &amp;device);
if (result != MA_SUCCESS) {
printf(&quot;Failed to initialize loopback device.\n&quot;);
return -2;
result = ma_device_init_ex(backends, <span style="color:#0033ff">sizeof</span>(backends)/<span style="color:#0033ff">sizeof</span>(backends[0]), NULL, &amp;deviceConfig, &amp;device);
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
printf(<span style="color:#cc3300">&quot;Failed to initialize loopback device.\n&quot;</span>);
<span style="color:#0033ff">return</span> -2;
}
result = ma_device_start(&amp;device);
if (result != MA_SUCCESS) {
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
ma_device_uninit(&amp;device);
printf(&quot;Failed to start device.\n&quot;);
return -3;
printf(<span style="color:#cc3300">&quot;Failed to start device.\n&quot;</span>);
<span style="color:#0033ff">return</span> -3;
}
printf(&quot;Press Enter to stop recording...\n&quot;);
printf(<span style="color:#cc3300">&quot;Press Enter to stop recording...\n&quot;</span>);
getchar();
ma_device_uninit(&amp;device);
ma_encoder_uninit(&amp;encoder);
return 0;
<span style="color:#0033ff">return</span> 0;
}
</pre></div></td>
</tr></table>
+29 -29
View File
@@ -250,44 +250,44 @@ This example uses a decoder as the data source. Decoders can be used with the <s
supports looping via the <span style="font-family:monospace;">ma_data_source_read_pcm_frames()</span> API. To use it, all you need to do is pass a pointer to the
decoder straight into <span style="font-family:monospace;">ma_data_source_read_pcm_frames()</span> and it will just work.</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
#define MINIAUDIO_IMPLEMENTATION
#include &quot;../miniaudio.h&quot;
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
<span style="color:#666666">#include</span> <span style="color:#cc3300">&quot;../miniaudio.h&quot;</span>
#include &lt;stdio.h&gt;
<span style="color:#666666">#include</span> <span style="color:#cc3300">&lt;stdio.h&gt;</span>
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
<span style="color:#0033ff">void</span> data_callback(<span style="color:#0099cc">ma_device</span>* pDevice, <span style="color:#0033ff">void</span>* pOutput, <span style="color:#0033ff">const</span> <span style="color:#0033ff">void</span>* pInput, <span style="color:#0099cc">ma_uint32</span> frameCount)
{
ma_bool32 isLooping = MA_TRUE;
<span style="color:#0099cc">ma_bool32</span> isLooping = MA_TRUE;
ma_decoder* pDecoder = (ma_decoder*)pDevice-&gt;pUserData;
if (pDecoder == NULL) {
return;
<span style="color:#0099cc">ma_decoder</span>* pDecoder = (<span style="color:#0099cc">ma_decoder</span>*)pDevice-&gt;pUserData;
<span style="color:#0033ff">if</span> (pDecoder == NULL) {
<span style="color:#0033ff">return</span>;
}
/*
<span style="color:#009900">/*
A decoder is a data source which means you can seemlessly plug it into the ma_data_source API. We can therefore take advantage
of the &quot;loop&quot; parameter of ma_data_source_read_pcm_frames() to handle looping for us.
*/
*/</span>
ma_data_source_read_pcm_frames(pDecoder, pOutput, frameCount, NULL, isLooping);
(void)pInput;
(<span style="color:#0033ff">void</span>)pInput;
}
int main(int argc, char** argv)
<span style="color:#0033ff">int</span> main(<span style="color:#0033ff">int</span> argc, <span style="color:#0033ff">char</span>** argv)
{
ma_result result;
ma_decoder decoder;
ma_device_config deviceConfig;
ma_device device;
<span style="color:#0099cc">ma_result</span> result;
<span style="color:#0099cc">ma_decoder</span> decoder;
<span style="color:#0099cc">ma_device_config</span> deviceConfig;
<span style="color:#0099cc">ma_device</span> device;
if (argc &lt; 2) {
printf(&quot;No input file.\n&quot;);
return -1;
<span style="color:#0033ff">if</span> (argc &lt; 2) {
printf(<span style="color:#cc3300">&quot;No input file.\n&quot;</span>);
<span style="color:#0033ff">return</span> -1;
}
result = ma_decoder_init_file(argv[1], NULL, &amp;decoder);
if (result != MA_SUCCESS) {
return -2;
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#0033ff">return</span> -2;
}
deviceConfig = ma_device_config_init(ma_device_type_playback);
@@ -297,26 +297,26 @@ int main(int argc, char** argv)
deviceConfig.dataCallback = data_callback;
deviceConfig.pUserData = &amp;decoder;
if (ma_device_init(NULL, &amp;deviceConfig, &amp;device) != MA_SUCCESS) {
printf(&quot;Failed to open playback device.\n&quot;);
<span style="color:#0033ff">if</span> (ma_device_init(NULL, &amp;deviceConfig, &amp;device) != MA_SUCCESS) {
printf(<span style="color:#cc3300">&quot;Failed to open playback device.\n&quot;</span>);
ma_decoder_uninit(&amp;decoder);
return -3;
<span style="color:#0033ff">return</span> -3;
}
if (ma_device_start(&amp;device) != MA_SUCCESS) {
printf(&quot;Failed to start playback device.\n&quot;);
<span style="color:#0033ff">if</span> (ma_device_start(&amp;device) != MA_SUCCESS) {
printf(<span style="color:#cc3300">&quot;Failed to start playback device.\n&quot;</span>);
ma_device_uninit(&amp;device);
ma_decoder_uninit(&amp;decoder);
return -4;
<span style="color:#0033ff">return</span> -4;
}
printf(&quot;Press Enter to quit...&quot;);
printf(<span style="color:#cc3300">&quot;Press Enter to quit...&quot;</span>);
getchar();
ma_device_uninit(&amp;device);
ma_decoder_uninit(&amp;decoder);
return 0;
<span style="color:#0033ff">return</span> 0;
}
</pre></div></td>
</tr></table>
+84 -84
View File
@@ -258,139 +258,139 @@ is when sample are clampled to their minimum and maximum range, which for floati
Usage: simple_mixing [input file 0] [input file 1] ... [input file n]
Example: simple_mixing file1.wav file2.flac
</pre></div><div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
#define MINIAUDIO_IMPLEMENTATION
#include &quot;../miniaudio.h&quot;
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
<span style="color:#666666">#include</span> <span style="color:#cc3300">&quot;../miniaudio.h&quot;</span>
#include &lt;stdio.h&gt;
<span style="color:#666666">#include</span> <span style="color:#cc3300">&lt;stdio.h&gt;</span>
/*
<span style="color:#009900">/*
For simplicity, this example requires the device to use floating point samples.
*/
#define SAMPLE_FORMAT ma_format_f32
#define CHANNEL_COUNT 2
#define SAMPLE_RATE 48000
*/</span>
<span style="color:#666666">#define</span> SAMPLE_FORMAT ma_format_f32
<span style="color:#666666">#define</span> CHANNEL_COUNT 2
<span style="color:#666666">#define</span> SAMPLE_RATE 48000
ma_uint32 g_decoderCount;
ma_decoder* g_pDecoders;
ma_bool32* g_pDecodersAtEnd;
<span style="color:#0099cc">ma_uint32</span> g_decoderCount;
<span style="color:#0099cc">ma_decoder</span>* g_pDecoders;
<span style="color:#0099cc">ma_bool32</span>* g_pDecodersAtEnd;
ma_event g_stopEvent; /* &lt;-- Signaled by the audio thread, waited on by the main thread. */
<span style="color:#0099cc">ma_event</span> g_stopEvent; <span style="color:#009900">/* &lt;-- Signaled by the audio thread, waited on by the main thread. */</span>
ma_bool32 are_all_decoders_at_end()
<span style="color:#0099cc">ma_bool32</span> are_all_decoders_at_end()
{
ma_uint32 iDecoder;
for (iDecoder = 0; iDecoder &lt; g_decoderCount; ++iDecoder) {
if (g_pDecodersAtEnd[iDecoder] == MA_FALSE) {
return MA_FALSE;
<span style="color:#0099cc">ma_uint32</span> iDecoder;
<span style="color:#0033ff">for</span> (iDecoder = 0; iDecoder &lt; g_decoderCount; ++iDecoder) {
<span style="color:#0033ff">if</span> (g_pDecodersAtEnd[iDecoder] == MA_FALSE) {
<span style="color:#0033ff">return</span> MA_FALSE;
}
}
return MA_TRUE;
<span style="color:#0033ff">return</span> MA_TRUE;
}
ma_uint32 read_and_mix_pcm_frames_f32(ma_decoder* pDecoder, float* pOutputF32, ma_uint32 frameCount)
<span style="color:#0099cc">ma_uint32</span> read_and_mix_pcm_frames_f32(<span style="color:#0099cc">ma_decoder</span>* pDecoder, <span style="color:#0033ff">float</span>* pOutputF32, <span style="color:#0099cc">ma_uint32</span> frameCount)
{
/*
<span style="color:#009900">/*
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
contents of the output buffer by simply adding the samples together. You could also clip the samples to -1..+1, but I&#39;m not
doing that in this example.
*/
float temp[4096];
ma_uint32 tempCapInFrames = ma_countof(temp) / CHANNEL_COUNT;
ma_uint32 totalFramesRead = 0;
*/</span>
<span style="color:#0033ff">float</span> temp[4096];
<span style="color:#0099cc">ma_uint32</span> tempCapInFrames = ma_countof(temp) / CHANNEL_COUNT;
<span style="color:#0099cc">ma_uint32</span> totalFramesRead = 0;
while (totalFramesRead &lt; frameCount) {
ma_uint32 iSample;
ma_uint32 framesReadThisIteration;
ma_uint32 totalFramesRemaining = frameCount - totalFramesRead;
ma_uint32 framesToReadThisIteration = tempCapInFrames;
if (framesToReadThisIteration &gt; totalFramesRemaining) {
<span style="color:#0033ff">while</span> (totalFramesRead &lt; frameCount) {
<span style="color:#0099cc">ma_uint32</span> iSample;
<span style="color:#0099cc">ma_uint32</span> framesReadThisIteration;
<span style="color:#0099cc">ma_uint32</span> totalFramesRemaining = frameCount - totalFramesRead;
<span style="color:#0099cc">ma_uint32</span> framesToReadThisIteration = tempCapInFrames;
<span style="color:#0033ff">if</span> (framesToReadThisIteration &gt; totalFramesRemaining) {
framesToReadThisIteration = totalFramesRemaining;
}
framesReadThisIteration = (ma_uint32)ma_decoder_read_pcm_frames(pDecoder, temp, framesToReadThisIteration);
if (framesReadThisIteration == 0) {
break;
framesReadThisIteration = (<span style="color:#0099cc">ma_uint32</span>)ma_decoder_read_pcm_frames(pDecoder, temp, framesToReadThisIteration);
<span style="color:#0033ff">if</span> (framesReadThisIteration == 0) {
<span style="color:#0033ff">break</span>;
}
/* Mix the frames together. */
for (iSample = 0; iSample &lt; framesReadThisIteration*CHANNEL_COUNT; ++iSample) {
<span style="color:#009900">/* Mix the frames together. */</span>
<span style="color:#0033ff">for</span> (iSample = 0; iSample &lt; framesReadThisIteration*CHANNEL_COUNT; ++iSample) {
pOutputF32[totalFramesRead*CHANNEL_COUNT + iSample] += temp[iSample];
}
totalFramesRead += framesReadThisIteration;
if (framesReadThisIteration &lt; framesToReadThisIteration) {
break; /* Reached EOF. */
<span style="color:#0033ff">if</span> (framesReadThisIteration &lt; framesToReadThisIteration) {
<span style="color:#0033ff">break</span>; <span style="color:#009900">/* Reached EOF. */</span>
}
}
return totalFramesRead;
<span style="color:#0033ff">return</span> totalFramesRead;
}
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
<span style="color:#0033ff">void</span> data_callback(<span style="color:#0099cc">ma_device</span>* pDevice, <span style="color:#0033ff">void</span>* pOutput, <span style="color:#0033ff">const</span> <span style="color:#0033ff">void</span>* pInput, <span style="color:#0099cc">ma_uint32</span> frameCount)
{
float* pOutputF32 = (float*)pOutput;
ma_uint32 iDecoder;
<span style="color:#0033ff">float</span>* pOutputF32 = (<span style="color:#0033ff">float</span>*)pOutput;
<span style="color:#0099cc">ma_uint32</span> iDecoder;
MA_ASSERT(pDevice-&gt;playback.format == SAMPLE_FORMAT); /* &lt;-- Important for this example. */
MA_ASSERT(pDevice-&gt;playback.format == SAMPLE_FORMAT); <span style="color:#009900">/* &lt;-- Important for this example. */</span>
for (iDecoder = 0; iDecoder &lt; g_decoderCount; ++iDecoder) {
if (!g_pDecodersAtEnd[iDecoder]) {
ma_uint32 framesRead = read_and_mix_pcm_frames_f32(&amp;g_pDecoders[iDecoder], pOutputF32, frameCount);
if (framesRead &lt; frameCount) {
<span style="color:#0033ff">for</span> (iDecoder = 0; iDecoder &lt; g_decoderCount; ++iDecoder) {
<span style="color:#0033ff">if</span> (!g_pDecodersAtEnd[iDecoder]) {
<span style="color:#0099cc">ma_uint32</span> framesRead = read_and_mix_pcm_frames_f32(&amp;g_pDecoders[iDecoder], pOutputF32, frameCount);
<span style="color:#0033ff">if</span> (framesRead &lt; frameCount) {
g_pDecodersAtEnd[iDecoder] = MA_TRUE;
}
}
}
/*
<span style="color:#009900">/*
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
signal an event to indicate that it&#39;s stopped. The main thread will be waiting on the event, after which it will stop the device.
*/
if (are_all_decoders_at_end()) {
*/</span>
<span style="color:#0033ff">if</span> (are_all_decoders_at_end()) {
ma_event_signal(&amp;g_stopEvent);
}
(void)pInput;
(<span style="color:#0033ff">void</span>)pInput;
}
int main(int argc, char** argv)
<span style="color:#0033ff">int</span> main(<span style="color:#0033ff">int</span> argc, <span style="color:#0033ff">char</span>** argv)
{
ma_result result;
ma_decoder_config decoderConfig;
ma_device_config deviceConfig;
ma_device device;
ma_uint32 iDecoder;
<span style="color:#0099cc">ma_result</span> result;
<span style="color:#0099cc">ma_decoder_config</span> decoderConfig;
<span style="color:#0099cc">ma_device_config</span> deviceConfig;
<span style="color:#0099cc">ma_device</span> device;
<span style="color:#0099cc">ma_uint32</span> iDecoder;
if (argc &lt; 2) {
printf(&quot;No input files.\n&quot;);
return -1;
<span style="color:#0033ff">if</span> (argc &lt; 2) {
printf(<span style="color:#cc3300">&quot;No input files.\n&quot;</span>);
<span style="color:#0033ff">return</span> -1;
}
g_decoderCount = argc-1;
g_pDecoders = (ma_decoder*)malloc(sizeof(*g_pDecoders) * g_decoderCount);
g_pDecodersAtEnd = (ma_bool32*) malloc(sizeof(*g_pDecodersAtEnd) * g_decoderCount);
g_pDecoders = (<span style="color:#0099cc">ma_decoder</span>*)malloc(<span style="color:#0033ff">sizeof</span>(*g_pDecoders) * g_decoderCount);
g_pDecodersAtEnd = (<span style="color:#0099cc">ma_bool32</span>*) malloc(<span style="color:#0033ff">sizeof</span>(*g_pDecodersAtEnd) * g_decoderCount);
/* In this example, all decoders need to have the same output format. */
<span style="color:#009900">/* In this example, all decoders need to have the same output format. */</span>
decoderConfig = ma_decoder_config_init(SAMPLE_FORMAT, CHANNEL_COUNT, SAMPLE_RATE);
for (iDecoder = 0; iDecoder &lt; g_decoderCount; ++iDecoder) {
<span style="color:#0033ff">for</span> (iDecoder = 0; iDecoder &lt; g_decoderCount; ++iDecoder) {
result = ma_decoder_init_file(argv[1+iDecoder], &amp;decoderConfig, &amp;g_pDecoders[iDecoder]);
if (result != MA_SUCCESS) {
ma_uint32 iDecoder2;
for (iDecoder2 = 0; iDecoder2 &lt; iDecoder; ++iDecoder2) {
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#0099cc">ma_uint32</span> iDecoder2;
<span style="color:#0033ff">for</span> (iDecoder2 = 0; iDecoder2 &lt; iDecoder; ++iDecoder2) {
ma_decoder_uninit(&amp;g_pDecoders[iDecoder2]);
}
free(g_pDecoders);
free(g_pDecodersAtEnd);
printf(&quot;Failed to load %s.\n&quot;, argv[1+iDecoder]);
return -3;
printf(<span style="color:#cc3300">&quot;Failed to load %s.\n&quot;</span>, argv[1+iDecoder]);
<span style="color:#0033ff">return</span> -3;
}
g_pDecodersAtEnd[iDecoder] = MA_FALSE;
}
/* 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. */
<span style="color:#009900">/* 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. */</span>
deviceConfig = ma_device_config_init(ma_device_type_playback);
deviceConfig.playback.format = SAMPLE_FORMAT;
deviceConfig.playback.channels = CHANNEL_COUNT;
@@ -398,50 +398,50 @@ int main(int argc, char** argv)
deviceConfig.dataCallback = data_callback;
deviceConfig.pUserData = NULL;
if (ma_device_init(NULL, &amp;deviceConfig, &amp;device) != MA_SUCCESS) {
for (iDecoder = 0; iDecoder &lt; g_decoderCount; ++iDecoder) {
<span style="color:#0033ff">if</span> (ma_device_init(NULL, &amp;deviceConfig, &amp;device) != MA_SUCCESS) {
<span style="color:#0033ff">for</span> (iDecoder = 0; iDecoder &lt; g_decoderCount; ++iDecoder) {
ma_decoder_uninit(&amp;g_pDecoders[iDecoder]);
}
free(g_pDecoders);
free(g_pDecodersAtEnd);
printf(&quot;Failed to open playback device.\n&quot;);
return -3;
printf(<span style="color:#cc3300">&quot;Failed to open playback device.\n&quot;</span>);
<span style="color:#0033ff">return</span> -3;
}
/*
<span style="color:#009900">/*
We can&#39;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
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
a context separately, but we don&#39;t need to do that for this example.
*/
*/</span>
ma_event_init(&amp;g_stopEvent);
/* Now we start playback and wait for the audio thread to tell us to stop. */
if (ma_device_start(&amp;device) != MA_SUCCESS) {
<span style="color:#009900">/* Now we start playback and wait for the audio thread to tell us to stop. */</span>
<span style="color:#0033ff">if</span> (ma_device_start(&amp;device) != MA_SUCCESS) {
ma_device_uninit(&amp;device);
for (iDecoder = 0; iDecoder &lt; g_decoderCount; ++iDecoder) {
<span style="color:#0033ff">for</span> (iDecoder = 0; iDecoder &lt; g_decoderCount; ++iDecoder) {
ma_decoder_uninit(&amp;g_pDecoders[iDecoder]);
}
free(g_pDecoders);
free(g_pDecodersAtEnd);
printf(&quot;Failed to start playback device.\n&quot;);
return -4;
printf(<span style="color:#cc3300">&quot;Failed to start playback device.\n&quot;</span>);
<span style="color:#0033ff">return</span> -4;
}
printf(&quot;Waiting for playback to complete...\n&quot;);
printf(<span style="color:#cc3300">&quot;Waiting for playback to complete...\n&quot;</span>);
ma_event_wait(&amp;g_stopEvent);
/* Getting here means the audio thread has signaled that the device should be stopped. */
<span style="color:#009900">/* Getting here means the audio thread has signaled that the device should be stopped. */</span>
ma_device_uninit(&amp;device);
for (iDecoder = 0; iDecoder &lt; g_decoderCount; ++iDecoder) {
<span style="color:#0033ff">for</span> (iDecoder = 0; iDecoder &lt; g_decoderCount; ++iDecoder) {
ma_decoder_uninit(&amp;g_pDecoders[iDecoder]);
}
free(g_pDecoders);
free(g_pDecodersAtEnd);
return 0;
<span style="color:#0033ff">return</span> 0;
}
</pre></div></td>
</tr></table>
+26 -26
View File
@@ -257,38 +257,38 @@ device and can be used independently of it. This example only plays back a singl
back multiple files by simple loading multiple decoders and mixing them (do not create multiple devices to do this). See
the simple_mixing example for how best to do this.</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
#define MINIAUDIO_IMPLEMENTATION
#include &quot;../miniaudio.h&quot;
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
<span style="color:#666666">#include</span> <span style="color:#cc3300">&quot;../miniaudio.h&quot;</span>
#include &lt;stdio.h&gt;
<span style="color:#666666">#include</span> <span style="color:#cc3300">&lt;stdio.h&gt;</span>
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
<span style="color:#0033ff">void</span> data_callback(<span style="color:#0099cc">ma_device</span>* pDevice, <span style="color:#0033ff">void</span>* pOutput, <span style="color:#0033ff">const</span> <span style="color:#0033ff">void</span>* pInput, <span style="color:#0099cc">ma_uint32</span> frameCount)
{
ma_decoder* pDecoder = (ma_decoder*)pDevice-&gt;pUserData;
if (pDecoder == NULL) {
return;
<span style="color:#0099cc">ma_decoder</span>* pDecoder = (<span style="color:#0099cc">ma_decoder</span>*)pDevice-&gt;pUserData;
<span style="color:#0033ff">if</span> (pDecoder == NULL) {
<span style="color:#0033ff">return</span>;
}
ma_decoder_read_pcm_frames(pDecoder, pOutput, frameCount);
(void)pInput;
(<span style="color:#0033ff">void</span>)pInput;
}
int main(int argc, char** argv)
<span style="color:#0033ff">int</span> main(<span style="color:#0033ff">int</span> argc, <span style="color:#0033ff">char</span>** argv)
{
ma_result result;
ma_decoder decoder;
ma_device_config deviceConfig;
ma_device device;
<span style="color:#0099cc">ma_result</span> result;
<span style="color:#0099cc">ma_decoder</span> decoder;
<span style="color:#0099cc">ma_device_config</span> deviceConfig;
<span style="color:#0099cc">ma_device</span> device;
if (argc &lt; 2) {
printf(&quot;No input file.\n&quot;);
return -1;
<span style="color:#0033ff">if</span> (argc &lt; 2) {
printf(<span style="color:#cc3300">&quot;No input file.\n&quot;</span>);
<span style="color:#0033ff">return</span> -1;
}
result = ma_decoder_init_file(argv[1], NULL, &amp;decoder);
if (result != MA_SUCCESS) {
return -2;
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#0033ff">return</span> -2;
}
deviceConfig = ma_device_config_init(ma_device_type_playback);
@@ -298,26 +298,26 @@ int main(int argc, char** argv)
deviceConfig.dataCallback = data_callback;
deviceConfig.pUserData = &amp;decoder;
if (ma_device_init(NULL, &amp;deviceConfig, &amp;device) != MA_SUCCESS) {
printf(&quot;Failed to open playback device.\n&quot;);
<span style="color:#0033ff">if</span> (ma_device_init(NULL, &amp;deviceConfig, &amp;device) != MA_SUCCESS) {
printf(<span style="color:#cc3300">&quot;Failed to open playback device.\n&quot;</span>);
ma_decoder_uninit(&amp;decoder);
return -3;
<span style="color:#0033ff">return</span> -3;
}
if (ma_device_start(&amp;device) != MA_SUCCESS) {
printf(&quot;Failed to start playback device.\n&quot;);
<span style="color:#0033ff">if</span> (ma_device_start(&amp;device) != MA_SUCCESS) {
printf(<span style="color:#cc3300">&quot;Failed to start playback device.\n&quot;</span>);
ma_device_uninit(&amp;device);
ma_decoder_uninit(&amp;decoder);
return -4;
<span style="color:#0033ff">return</span> -4;
}
printf(&quot;Press Enter to quit...&quot;);
printf(<span style="color:#cc3300">&quot;Press Enter to quit...&quot;</span>);
getchar();
ma_device_uninit(&amp;device);
ma_decoder_uninit(&amp;decoder);
return 0;
<span style="color:#0033ff">return</span> 0;
}
</pre></div></td>
</tr></table>
+35 -35
View File
@@ -263,45 +263,45 @@ the <span style="font-family:monospace;">ma_waveform_read_pcm_frames()</span> AP
This example works with Emscripten.</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
#define MA_NO_DECODING
#define MA_NO_ENCODING
#define MINIAUDIO_IMPLEMENTATION
#include &quot;../miniaudio.h&quot;
<span style="color:#666666">#define</span> MA_NO_DECODING
<span style="color:#666666">#define</span> MA_NO_ENCODING
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
<span style="color:#666666">#include</span> <span style="color:#cc3300">&quot;../miniaudio.h&quot;</span>
#include &lt;stdio.h&gt;
<span style="color:#666666">#include</span> <span style="color:#cc3300">&lt;stdio.h&gt;</span>
#ifdef __EMSCRIPTEN__
#include &lt;emscripten.h&gt;
<span style="color:#666666">#ifdef</span> __EMSCRIPTEN__
<span style="color:#666666">#include</span> <span style="color:#cc3300">&lt;emscripten.h&gt;</span>
void main_loop__em()
<span style="color:#0033ff">void</span> main_loop__em()
{
}
#endif
<span style="color:#666666">#endif</span>
#define DEVICE_FORMAT ma_format_f32
#define DEVICE_CHANNELS 2
#define DEVICE_SAMPLE_RATE 48000
<span style="color:#666666">#define</span> DEVICE_FORMAT ma_format_f32
<span style="color:#666666">#define</span> DEVICE_CHANNELS 2
<span style="color:#666666">#define</span> DEVICE_SAMPLE_RATE 48000
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
<span style="color:#0033ff">void</span> data_callback(<span style="color:#0099cc">ma_device</span>* pDevice, <span style="color:#0033ff">void</span>* pOutput, <span style="color:#0033ff">const</span> <span style="color:#0033ff">void</span>* pInput, <span style="color:#0099cc">ma_uint32</span> frameCount)
{
ma_waveform* pSineWave;
<span style="color:#0099cc">ma_waveform</span>* pSineWave;
MA_ASSERT(pDevice-&gt;playback.channels == DEVICE_CHANNELS);
pSineWave = (ma_waveform*)pDevice-&gt;pUserData;
pSineWave = (<span style="color:#0099cc">ma_waveform</span>*)pDevice-&gt;pUserData;
MA_ASSERT(pSineWave != NULL);
ma_waveform_read_pcm_frames(pSineWave, pOutput, frameCount);
(void)pInput; /* Unused. */
(<span style="color:#0033ff">void</span>)pInput; <span style="color:#009900">/* Unused. */</span>
}
int main(int argc, char** argv)
<span style="color:#0033ff">int</span> main(<span style="color:#0033ff">int</span> argc, <span style="color:#0033ff">char</span>** argv)
{
ma_waveform sineWave;
ma_device_config deviceConfig;
ma_device device;
ma_waveform_config sineWaveConfig;
<span style="color:#0099cc">ma_waveform</span> sineWave;
<span style="color:#0099cc">ma_device_config</span> deviceConfig;
<span style="color:#0099cc">ma_device</span> device;
<span style="color:#0099cc">ma_waveform_config</span> sineWaveConfig;
sineWaveConfig = ma_waveform_config_init(DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, ma_waveform_type_sine, 0.2, 220);
ma_waveform_init(&amp;sineWaveConfig, &amp;sineWave);
@@ -313,31 +313,31 @@ int main(int argc, char** argv)
deviceConfig.dataCallback = data_callback;
deviceConfig.pUserData = &amp;sineWave;
if (ma_device_init(NULL, &amp;deviceConfig, &amp;device) != MA_SUCCESS) {
printf(&quot;Failed to open playback device.\n&quot;);
return -4;
<span style="color:#0033ff">if</span> (ma_device_init(NULL, &amp;deviceConfig, &amp;device) != MA_SUCCESS) {
printf(<span style="color:#cc3300">&quot;Failed to open playback device.\n&quot;</span>);
<span style="color:#0033ff">return</span> -4;
}
printf(&quot;Device Name: %s\n&quot;, device.playback.name);
printf(<span style="color:#cc3300">&quot;Device Name: %s\n&quot;</span>, device.playback.name);
if (ma_device_start(&amp;device) != MA_SUCCESS) {
printf(&quot;Failed to start playback device.\n&quot;);
<span style="color:#0033ff">if</span> (ma_device_start(&amp;device) != MA_SUCCESS) {
printf(<span style="color:#cc3300">&quot;Failed to start playback device.\n&quot;</span>);
ma_device_uninit(&amp;device);
return -5;
<span style="color:#0033ff">return</span> -5;
}
#ifdef __EMSCRIPTEN__
<span style="color:#666666">#ifdef</span> __EMSCRIPTEN__
emscripten_set_main_loop(main_loop__em, 0, 1);
#else
printf(&quot;Press Enter to quit...\n&quot;);
<span style="color:#666666">#else</span>
printf(<span style="color:#cc3300">&quot;Press Enter to quit...\n&quot;</span>);
getchar();
#endif
<span style="color:#666666">#endif</span>
ma_device_uninit(&amp;device);
(void)argc;
(void)argv;
return 0;
(<span style="color:#0033ff">void</span>)argc;
(<span style="color:#0033ff">void</span>)argv;
<span style="color:#0033ff">return</span> 0;
}
</pre></div></td>
</tr></table>
+135 -135
View File
@@ -253,8 +253,8 @@ miniaudio is a single file library for audio playback and capture. To use it, do
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
#define MINIAUDIO_IMPLEMENTATION
#include &quot;miniaudio.h&quot;
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
<span style="color:#666666">#include</span> <span style="color:#cc3300">&quot;miniaudio.h&quot;</span>
</pre></div><p>
You can do <span style="font-family:monospace;">#include miniaudio.h</span> in other parts of the program just like any other header.
@@ -280,32 +280,32 @@ but you could allocate it on the heap if that suits your situation better.
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
<span style="color:#0033ff">void</span> data_callback(<span style="color:#0099cc">ma_device</span>* pDevice, <span style="color:#0033ff">void</span>* pOutput, <span style="color:#0033ff">const</span> <span style="color:#0033ff">void</span>* pInput, <span style="color:#0099cc">ma_uint32</span> frameCount)
{
// In playback mode copy data to pOutput. In capture mode read data from pInput. In full-duplex mode, both
// pOutput and pInput will be valid and you can move data from pInput into pOutput. Never process more than
// frameCount frames.
<span style="color:#009900">// In playback mode copy data to pOutput. In capture mode read data from pInput. In full-duplex mode, both</span>
<span style="color:#009900">// pOutput and pInput will be valid and you can move data from pInput into pOutput. Never process more than</span>
<span style="color:#009900">// frameCount frames.</span>
}
...
ma_device_config config = ma_device_config_init(ma_device_type_playback);
<span style="color:#0099cc">ma_device_config</span> config = ma_device_config_init(ma_device_type_playback);
config.playback.format = MY_FORMAT;
config.playback.channels = MY_CHANNEL_COUNT;
config.sampleRate = MY_SAMPLE_RATE;
config.dataCallback = data_callback;
config.pUserData = pMyCustomData; // Can be accessed from the device object (device.pUserData).
config.pUserData = pMyCustomData; <span style="color:#009900">// Can be accessed from the device object (device.pUserData).</span>
ma_device device;
if (ma_device_init(NULL, &amp;config, &amp;device) != MA_SUCCESS) {
<span style="color:#0099cc">ma_device</span> device;
<span style="color:#0033ff">if</span> (ma_device_init(NULL, &amp;config, &amp;device) != MA_SUCCESS) {
... An error occurred ...
}
ma_device_start(&amp;device); // The device is sleeping by default so you&#39;ll need to start it manually.
ma_device_start(&amp;device); <span style="color:#009900">// The device is sleeping by default so you&#39;ll need to start it manually.</span>
...
ma_device_uninit(&amp;device); // This will stop the device so no need to do that manually.
ma_device_uninit(&amp;device); <span style="color:#009900">// This will stop the device so no need to do that manually.</span>
</pre></div><p>
In the example above, <span style="font-family:monospace;">data_callback()</span> is where audio data is written and read from the device. The idea is in playback mode you cause sound to be emitted
@@ -442,7 +442,7 @@ from <span style="font-family:monospace;">ma_device_type_playback</span> to <spa
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_device_config config = ma_device_config_init(ma_device_type_capture);
<span style="color:#0099cc">ma_device_config</span> config = ma_device_config_init(ma_device_type_capture);
config.capture.format = MY_FORMAT;
config.capture.channels = MY_CHANNEL_COUNT;
</pre></div><p>
@@ -512,8 +512,8 @@ devices connected and you want to use a specific one you will need to specify th
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
config.playback.pDeviceID = pMyPlaybackDeviceID; // Only if requesting a playback or duplex device.
config.capture.pDeviceID = pMyCaptureDeviceID; // Only if requesting a capture, duplex or loopback device.
config.playback.pDeviceID = pMyPlaybackDeviceID; <span style="color:#009900">// Only if requesting a playback or duplex device.</span>
config.capture.pDeviceID = pMyCaptureDeviceID; <span style="color:#009900">// Only if requesting a capture, duplex or loopback device.</span>
</pre></div><p>
To retrieve the device ID you will need to perform device enumeration, however this requires the use of a new concept called the &quot;context&quot;. Conceptually
@@ -525,26 +525,26 @@ backends and enumerating devices. The example below shows how to enumerate devic
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_context context;
if (ma_context_init(NULL, 0, NULL, &amp;context) != MA_SUCCESS) {
// Error.
<span style="color:#0099cc">ma_context</span> context;
<span style="color:#0033ff">if</span> (ma_context_init(NULL, 0, NULL, &amp;context) != MA_SUCCESS) {
<span style="color:#009900">// Error.</span>
}
ma_device_info* pPlaybackDeviceInfos;
ma_uint32 playbackDeviceCount;
ma_device_info* pCaptureDeviceInfos;
ma_uint32 captureDeviceCount;
if (ma_context_get_devices(&amp;context, &amp;pPlaybackDeviceInfos, &amp;playbackDeviceCount, &amp;pCaptureDeviceInfos, &amp;captureDeviceCount) != MA_SUCCESS) {
// Error.
<span style="color:#0099cc">ma_device_info</span>* pPlaybackDeviceInfos;
<span style="color:#0099cc">ma_uint32</span> playbackDeviceCount;
<span style="color:#0099cc">ma_device_info</span>* pCaptureDeviceInfos;
<span style="color:#0099cc">ma_uint32</span> captureDeviceCount;
<span style="color:#0033ff">if</span> (ma_context_get_devices(&amp;context, &amp;pPlaybackDeviceInfos, &amp;playbackDeviceCount, &amp;pCaptureDeviceInfos, &amp;captureDeviceCount) != MA_SUCCESS) {
<span style="color:#009900">// Error.</span>
}
// Loop over each device info and do something with it. Here we just print the name with their index. You may want to give the user the
// opportunity to choose which device they&#39;d prefer.
for (ma_uint32 iDevice = 0; iDevice &lt; playbackDeviceCount; iDevice += 1) {
printf(&quot;%d - %s\n&quot;, iDevice, pPlaybackDeviceInfos[iDevice].name);
<span style="color:#009900">// Loop over each device info and do something with it. Here we just print the name with their index. You may want to give the user the</span>
<span style="color:#009900">// opportunity to choose which device they&#39;d prefer.</span>
<span style="color:#0033ff">for</span> (<span style="color:#0099cc">ma_uint32</span> iDevice = 0; iDevice &lt; playbackDeviceCount; iDevice += 1) {
printf(<span style="color:#cc3300">&quot;%d - %s\n&quot;</span>, iDevice, pPlaybackDeviceInfos[iDevice].name);
}
ma_device_config config = ma_device_config_init(ma_device_type_playback);
<span style="color:#0099cc">ma_device_config</span> config = ma_device_config_init(ma_device_type_playback);
config.playback.pDeviceID = &amp;pPlaybackDeviceInfos[chosenPlaybackDeviceIndex].id;
config.playback.format = MY_FORMAT;
config.playback.channels = MY_CHANNEL_COUNT;
@@ -552,9 +552,9 @@ config.sampleRate = MY_SAMPLE_RATE;
config.dataCallback = data_callback;
config.pUserData = pMyCustomData;
ma_device device;
if (ma_device_init(&amp;context, &amp;config, &amp;device) != MA_SUCCESS) {
// Error
<span style="color:#0099cc">ma_device</span> device;
<span style="color:#0033ff">if</span> (ma_device_init(&amp;context, &amp;config, &amp;device) != MA_SUCCESS) {
<span style="color:#009900">// Error</span>
}
...
@@ -1098,15 +1098,15 @@ can be enabled by including the header section before the implementation of mini
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
#define STB_VORBIS_HEADER_ONLY
#include &quot;extras/stb_vorbis.c&quot; // Enables Vorbis decoding.
<span style="color:#666666">#define</span> STB_VORBIS_HEADER_ONLY
<span style="color:#666666">#include</span> <span style="color:#cc3300">&quot;extras/stb_vorbis.c&quot;</span> <span style="color:#009900">// Enables Vorbis decoding.</span>
#define MINIAUDIO_IMPLEMENTATION
#include &quot;miniaudio.h&quot;
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
<span style="color:#666666">#include</span> <span style="color:#cc3300">&quot;miniaudio.h&quot;</span>
// The stb_vorbis implementation must come after the implementation of miniaudio.
#undef STB_VORBIS_HEADER_ONLY
#include &quot;extras/stb_vorbis.c&quot;
<span style="color:#009900">// The stb_vorbis implementation must come after the implementation of miniaudio.</span>
<span style="color:#666666">#undef</span> STB_VORBIS_HEADER_ONLY
<span style="color:#666666">#include</span> <span style="color:#cc3300">&quot;extras/stb_vorbis.c&quot;</span>
</pre></div><p>
A copy of stb_vorbis is included in the &quot;extras&quot; folder in the miniaudio repository (<a href="https://github.com/dr-soft/miniaudio">https://github.com/dr-soft/miniaudio</a>).
@@ -1120,9 +1120,9 @@ built-in decoders by specifying one or more of the following options before the
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
#define MA_NO_WAV
#define MA_NO_FLAC
#define MA_NO_MP3
<span style="color:#666666">#define</span> MA_NO_WAV
<span style="color:#666666">#define</span> MA_NO_FLAC
<span style="color:#666666">#define</span> MA_NO_MP3
</pre></div><p>
Disabling built-in versions of dr_wav, dr_flac and dr_mp3 is useful if you use these libraries independantly of the <span style="font-family:monospace;">ma_decoder</span> API.
@@ -1136,10 +1136,10 @@ with <span style="font-family:monospace;">ma_decoder_init()</span>. Here is an e
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_decoder decoder;
ma_result result = ma_decoder_init_file(&quot;MySong.mp3&quot;, NULL, &amp;decoder);
if (result != MA_SUCCESS) {
return false; // An error occurred.
<span style="color:#0099cc">ma_decoder</span> decoder;
<span style="color:#0099cc">ma_result</span> result = ma_decoder_init_file(<span style="color:#cc3300">&quot;MySong.mp3&quot;</span>, NULL, &amp;decoder);
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#0033ff">return</span> false; <span style="color:#009900">// An error occurred.</span>
}
...
@@ -1154,7 +1154,7 @@ configure the output format, channel count, sample rate and channel map:
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_decoder_config config = ma_decoder_config_init(ma_format_f32, 2, 48000);
<span style="color:#0099cc">ma_decoder_config</span> config = ma_decoder_config_init(ma_format_f32, 2, 48000);
</pre></div><p>
When passing in NULL for decoder config in <span style="font-family:monospace;">ma_decoder_init*()</span>, the output format will be the same as that defined by the decoding backend.
@@ -1168,9 +1168,9 @@ PCM frames it means you&#39;ve reached the end:
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_uint64 framesRead = ma_decoder_read_pcm_frames(pDecoder, pFrames, framesToRead);
if (framesRead &lt; framesToRead) {
// Reached the end.
<span style="color:#0099cc">ma_uint64</span> framesRead = ma_decoder_read_pcm_frames(pDecoder, pFrames, framesToRead);
<span style="color:#0033ff">if</span> (framesRead &lt; framesToRead) {
<span style="color:#009900">// Reached the end.</span>
}
</pre></div><p>
@@ -1180,9 +1180,9 @@ You can also seek to a specific frame like so:
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_result result = ma_decoder_seek_to_pcm_frame(pDecoder, targetFrame);
if (result != MA_SUCCESS) {
return false; // An error occurred.
<span style="color:#0099cc">ma_result</span> result = ma_decoder_seek_to_pcm_frame(pDecoder, targetFrame);
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#0033ff">return</span> false; <span style="color:#009900">// An error occurred.</span>
}
</pre></div><p>
@@ -1231,7 +1231,7 @@ implementation section of miniaudio. This can be disabled by specifying the foll
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
#define MA_NO_WAV
<span style="color:#666666">#define</span> MA_NO_WAV
</pre></div><p>
An encoder can be initialized to write to a file with <span style="font-family:monospace;">ma_encoder_init_file()</span> or from data delivered via callbacks with <span style="font-family:monospace;">ma_encoder_init()</span>. Below is an
@@ -1241,11 +1241,11 @@ example for initializing an encoder to output to a file.
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_encoder_config config = ma_encoder_config_init(ma_resource_format_wav, FORMAT, CHANNELS, SAMPLE_RATE);
ma_encoder encoder;
ma_result result = ma_encoder_init_file(&quot;my_file.wav&quot;, &amp;config, &amp;encoder);
if (result != MA_SUCCESS) {
// Error
<span style="color:#0099cc">ma_encoder_config</span> config = ma_encoder_config_init(ma_resource_format_wav, FORMAT, CHANNELS, SAMPLE_RATE);
<span style="color:#0099cc">ma_encoder</span> encoder;
<span style="color:#0099cc">ma_result</span> result = ma_encoder_init_file(<span style="color:#cc3300">&quot;my_file.wav&quot;</span>, &amp;config, &amp;encoder);
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#009900">// Error</span>
}
...
@@ -1397,10 +1397,10 @@ conversion. Below is an example of initializing a simple channel converter which
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_channel_converter_config config = ma_channel_converter_config_init(ma_format, 1, NULL, 2, NULL, ma_channel_mix_mode_default, NULL);
<span style="color:#0099cc">ma_channel_converter_config</span> config = ma_channel_converter_config_init(ma_format, 1, NULL, 2, NULL, ma_channel_mix_mode_default, NULL);
result = ma_channel_converter_init(&amp;config, &amp;converter);
if (result != MA_SUCCESS) {
// Error.
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#009900">// Error.</span>
}
</pre></div><p>
@@ -1410,9 +1410,9 @@ To perform the conversion simply call <span style="font-family:monospace;">ma_ch
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_result result = ma_channel_converter_process_pcm_frames(&amp;converter, pFramesOut, pFramesIn, frameCount);
if (result != MA_SUCCESS) {
// Error.
<span style="color:#0099cc">ma_result</span> result = ma_channel_converter_process_pcm_frames(&amp;converter, pFramesOut, pFramesIn, frameCount);
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#009900">// Error.</span>
}
</pre></div><p>
@@ -1728,11 +1728,11 @@ Resampling is achieved with the <span style="font-family:monospace;">ma_resample
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_resampler_config config = ma_resampler_config_init(ma_format_s16, channels, sampleRateIn, sampleRateOut, ma_resample_algorithm_linear);
ma_resampler resampler;
ma_result result = ma_resampler_init(&amp;config, &amp;resampler);
if (result != MA_SUCCESS) {
// An error occurred...
<span style="color:#0099cc">ma_resampler_config</span> config = ma_resampler_config_init(ma_format_s16, channels, sampleRateIn, sampleRateOut, ma_resample_algorithm_linear);
<span style="color:#0099cc">ma_resampler</span> resampler;
<span style="color:#0099cc">ma_result</span> result = ma_resampler_init(&amp;config, &amp;resampler);
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#009900">// An error occurred...</span>
}
</pre></div><p>
@@ -1751,15 +1751,15 @@ The following example shows how data can be processed
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_uint64 frameCountIn = 1000;
ma_uint64 frameCountOut = 2000;
ma_result result = ma_resampler_process_pcm_frames(&amp;resampler, pFramesIn, &amp;frameCountIn, pFramesOut, &amp;frameCountOut);
if (result != MA_SUCCESS) {
// An error occurred...
<span style="color:#0099cc">ma_uint64</span> frameCountIn = 1000;
<span style="color:#0099cc">ma_uint64</span> frameCountOut = 2000;
<span style="color:#0099cc">ma_result</span> result = ma_resampler_process_pcm_frames(&amp;resampler, pFramesIn, &amp;frameCountIn, pFramesOut, &amp;frameCountOut);
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#009900">// An error occurred...</span>
}
// At this point, frameCountIn contains the number of input frames that were consumed and frameCountOut contains the
// number of output frames written.
<span style="color:#009900">// At this point, frameCountIn contains the number of input frames that were consumed and frameCountOut contains the</span>
<span style="color:#009900">// number of output frames written.</span>
</pre></div><p>
To initialize the resampler you first need to set up a config (<span style="font-family:monospace;">ma_resampler_config</span>) with <span style="font-family:monospace;">ma_resampler_config_init()</span>. You need to specify the sample format
@@ -1900,7 +1900,7 @@ source files. To opt-in, you must first #include the following file before the i
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
#include &quot;extras/speex_resampler/ma_speex_resampler.h&quot;
<span style="color:#666666">#include</span> <span style="color:#cc3300">&quot;extras/speex_resampler/ma_speex_resampler.h&quot;</span>
</pre></div><p>
Both the header and implementation is contained within the same file. The implementation can be included in your program like so:
@@ -1909,8 +1909,8 @@ Both the header and implementation is contained within the same file. The implem
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
#define MINIAUDIO_SPEEX_RESAMPLER_IMPLEMENTATION
#include &quot;extras/speex_resampler/ma_speex_resampler.h&quot;
<span style="color:#666666">#define</span> MINIAUDIO_SPEEX_RESAMPLER_IMPLEMENTATION
<span style="color:#666666">#include</span> <span style="color:#cc3300">&quot;extras/speex_resampler/ma_speex_resampler.h&quot;</span>
</pre></div><p>
Note that even if you opt-in to the Speex backend, miniaudio won&#39;t use it unless you explicitly ask for it in the respective config of the object you are
@@ -1940,7 +1940,7 @@ conversion is very similar to the resampling API. Create a <span style="font-fam
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_data_converter_config config = ma_data_converter_config_init(
<span style="color:#0099cc">ma_data_converter_config</span> config = ma_data_converter_config_init(
inputFormat,
outputFormat,
inputChannels,
@@ -1949,10 +1949,10 @@ ma_data_converter_config config = ma_data_converter_config_init(
outputSampleRate
);
ma_data_converter converter;
ma_result result = ma_data_converter_init(&amp;config, &amp;converter);
if (result != MA_SUCCESS) {
// An error occurred...
<span style="color:#0099cc">ma_data_converter</span> converter;
<span style="color:#0099cc">ma_result</span> result = ma_data_converter_init(&amp;config, &amp;converter);
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#009900">// An error occurred...</span>
}
</pre></div><p>
@@ -1963,7 +1963,7 @@ channel maps and resampling quality. Something like the following may be more su
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_data_converter_config config = ma_data_converter_config_init_default();
<span style="color:#0099cc">ma_data_converter_config</span> config = ma_data_converter_config_init_default();
config.formatIn = inputFormat;
config.formatOut = outputFormat;
config.channelsIn = inputChannels;
@@ -1989,15 +1989,15 @@ The following example shows how data can be processed
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_uint64 frameCountIn = 1000;
ma_uint64 frameCountOut = 2000;
ma_result result = ma_data_converter_process_pcm_frames(&amp;converter, pFramesIn, &amp;frameCountIn, pFramesOut, &amp;frameCountOut);
if (result != MA_SUCCESS) {
// An error occurred...
<span style="color:#0099cc">ma_uint64</span> frameCountIn = 1000;
<span style="color:#0099cc">ma_uint64</span> frameCountOut = 2000;
<span style="color:#0099cc">ma_result</span> result = ma_data_converter_process_pcm_frames(&amp;converter, pFramesIn, &amp;frameCountIn, pFramesOut, &amp;frameCountOut);
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#009900">// An error occurred...</span>
}
// At this point, frameCountIn contains the number of input frames that were consumed and frameCountOut contains the number
// of output frames written.
<span style="color:#009900">// At this point, frameCountIn contains the number of input frames that were consumed and frameCountOut contains the number</span>
<span style="color:#009900">// of output frames written.</span>
</pre></div><p>
The data converter supports multiple channels and is always interleaved (both input and output). The channel count cannot be changed after initialization.
@@ -2049,10 +2049,10 @@ Biquad filtering is achieved with the <span style="font-family:monospace;">ma_bi
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_biquad_config config = ma_biquad_config_init(ma_format_f32, channels, b0, b1, b2, a0, a1, a2);
ma_result result = ma_biquad_init(&amp;config, &amp;biquad);
if (result != MA_SUCCESS) {
// Error.
<span style="color:#0099cc">ma_biquad_config</span> config = ma_biquad_config_init(ma_format_f32, channels, b0, b1, b2, a0, a1, a2);
<span style="color:#0099cc">ma_result</span> result = ma_biquad_init(&amp;config, &amp;biquad);
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#009900">// Error.</span>
}
...
@@ -2140,10 +2140,10 @@ Low-pass filter example:
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_lpf_config config = ma_lpf_config_init(ma_format_f32, channels, sampleRate, cutoffFrequency, order);
ma_result result = ma_lpf_init(&amp;config, &amp;lpf);
if (result != MA_SUCCESS) {
// Error.
<span style="color:#0099cc">ma_lpf_config</span> config = ma_lpf_config_init(ma_format_f32, channels, sampleRate, cutoffFrequency, order);
<span style="color:#0099cc">ma_result</span> result = ma_lpf_init(&amp;config, &amp;lpf);
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#009900">// Error.</span>
}
...
@@ -2171,7 +2171,7 @@ The maximum filter order is limited to MA_MAX_FILTER_ORDER which is set to 8. If
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
for (iFilter = 0; iFilter &lt; filterCount; iFilter += 1) {
<span style="color:#0033ff">for</span> (iFilter = 0; iFilter &lt; filterCount; iFilter += 1) {
ma_lpf2_process_pcm_frames(&amp;lpf2[iFilter], pMyData, pMyData, frameCount);
}
</pre></div><p>
@@ -2422,12 +2422,12 @@ miniaudio supports generation of sine, square, triangle and sawtooth waveforms.
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_waveform_config config = ma_waveform_config_init(FORMAT, CHANNELS, SAMPLE_RATE, ma_waveform_type_sine, amplitude, frequency);
<span style="color:#0099cc">ma_waveform_config</span> config = ma_waveform_config_init(FORMAT, CHANNELS, SAMPLE_RATE, ma_waveform_type_sine, amplitude, frequency);
ma_waveform waveform;
ma_result result = ma_waveform_init(&amp;config, &amp;waveform);
if (result != MA_SUCCESS) {
// Error.
<span style="color:#0099cc">ma_waveform</span> waveform;
<span style="color:#0099cc">ma_result</span> result = ma_waveform_init(&amp;config, &amp;waveform);
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#009900">// Error.</span>
}
...
@@ -2489,12 +2489,12 @@ miniaudio supports generation of white, pink and Brownian noise via the <span st
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_noise_config config = ma_noise_config_init(FORMAT, CHANNELS, ma_noise_type_white, SEED, amplitude);
<span style="color:#0099cc">ma_noise_config</span> config = ma_noise_config_init(FORMAT, CHANNELS, ma_noise_type_white, SEED, amplitude);
ma_noise noise;
ma_result result = ma_noise_init(&amp;config, &amp;noise);
if (result != MA_SUCCESS) {
// Error.
<span style="color:#0099cc">ma_noise</span> noise;
<span style="color:#0099cc">ma_result</span> result = ma_noise_init(&amp;config, &amp;noise);
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#009900">// Error.</span>
}
...
@@ -2561,11 +2561,11 @@ Audio buffers are initialised using the standard configuration system used every
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_audio_buffer_config config = ma_audio_buffer_config_init(format, channels, sizeInFrames, pExistingData, &amp;allocationCallbacks);
ma_audio_buffer buffer;
<span style="color:#0099cc">ma_audio_buffer_config</span> config = ma_audio_buffer_config_init(format, channels, sizeInFrames, pExistingData, &amp;allocationCallbacks);
<span style="color:#0099cc">ma_audio_buffer</span> buffer;
result = ma_audio_buffer_init(&amp;config, &amp;buffer);
if (result != MA_SUCCESS) {
// Error.
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#009900">// Error.</span>
}
...
@@ -2585,11 +2585,11 @@ the raw audio data will be located immediately after the <span style="font-famil
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_audio_buffer_config config = ma_audio_buffer_config_init(format, channels, sizeInFrames, pExistingData, &amp;allocationCallbacks);
ma_audio_buffer* pBuffer
<span style="color:#0099cc">ma_audio_buffer_config</span> config = ma_audio_buffer_config_init(format, channels, sizeInFrames, pExistingData, &amp;allocationCallbacks);
<span style="color:#0099cc">ma_audio_buffer</span>* pBuffer
result = ma_audio_buffer_alloc_and_init(&amp;config, &amp;pBuffer);
if (result != MA_SUCCESS) {
// Error
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#009900">// Error</span>
}
...
@@ -2611,9 +2611,9 @@ with with <span style="font-family:monospace;">ma_audio_buffer_seek_to_pcm_frame
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_uint64 framesRead = ma_audio_buffer_read_pcm_frames(pAudioBuffer, pFramesOut, desiredFrameCount, isLooping);
if (framesRead &lt; desiredFrameCount) {
// If not looping, this means the end has been reached. This should never happen in looping mode with valid input.
<span style="color:#0099cc">ma_uint64</span> framesRead = ma_audio_buffer_read_pcm_frames(pAudioBuffer, pFramesOut, desiredFrameCount, isLooping);
<span style="color:#0033ff">if</span> (framesRead &lt; desiredFrameCount) {
<span style="color:#009900">// If not looping, this means the end has been reached. This should never happen in looping mode with valid input.</span>
}
</pre></div><p>
@@ -2624,15 +2624,15 @@ pointer to a segment of data:
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
void* pMappedFrames;
ma_uint64 frameCount = frameCountToTryMapping;
ma_result result = ma_audio_buffer_map(pAudioBuffer, &amp;pMappedFrames, &amp;frameCount);
if (result == MA_SUCCESS) {
// Map was successful. The value in frameCount will be how many frames were _actually_ mapped, which may be
// less due to the end of the buffer being reached.
<span style="color:#0033ff">void</span>* pMappedFrames;
<span style="color:#0099cc">ma_uint64</span> frameCount = frameCountToTryMapping;
<span style="color:#0099cc">ma_result</span> result = ma_audio_buffer_map(pAudioBuffer, &amp;pMappedFrames, &amp;frameCount);
<span style="color:#0033ff">if</span> (result == MA_SUCCESS) {
<span style="color:#009900">// Map was successful. The value in frameCount will be how many frames were _actually_ mapped, which may be</span>
<span style="color:#009900">// less due to the end of the buffer being reached.</span>
ma_copy_pcm_frames(pFramesOut, pMappedFrames, frameCount, pAudioBuffer-&gt;format, pAudioBuffer-&gt;channels);
// You must unmap the buffer.
<span style="color:#009900">// You must unmap the buffer.</span>
ma_audio_buffer_unmap(pAudioBuffer, frameCount);
}
</pre></div><p>
@@ -2670,10 +2670,10 @@ something like the following:
</p>
<div style="font-family:monospace; border:solid 1px #003800; border-left:solid 0.5em #003800; margin:1em 0em;"><pre style="margin:0.5em 1em; padding:0; line-height:125%">
ma_pcm_rb rb;
ma_result result = ma_pcm_rb_init(FORMAT, CHANNELS, BUFFER_SIZE_IN_FRAMES, NULL, NULL, &amp;rb);
if (result != MA_SUCCESS) {
// Error
<span style="color:#0099cc">ma_pcm_rb</span> rb;
<span style="color:#0099cc">ma_result</span> result = ma_pcm_rb_init(FORMAT, CHANNELS, BUFFER_SIZE_IN_FRAMES, NULL, NULL, &amp;rb);
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
<span style="color:#009900">// Error</span>
}
</pre></div><p>
@@ -2958,7 +2958,7 @@ UWP requires the Microphone capability to be enabled in the application&#39;s ma
&lt;Package ...&gt;
...
&lt;Capabilities&gt;
&lt;DeviceCapability Name=&quot;microphone&quot; /&gt;
&lt;DeviceCapability Name=<span style="color:#cc3300">&quot;microphone&quot;</span> /&gt;
&lt;/Capabilities&gt;
&lt;/Package&gt;
</pre></div><p>