mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-22 16:24:04 +02:00
Add syntax highlighting to documentation.
This commit is contained in:
@@ -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 "../miniaudio.h"
|
||||
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300">"../miniaudio.h"</span>
|
||||
|
||||
#include <stdio.h>
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300"><stdio.h></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 /* <-- 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">/* <-- 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("frameCount=%d\n", frameCount);
|
||||
*/</span>
|
||||
printf(<span style="color:#cc3300">"frameCount=%d\n"</span>, frameCount);
|
||||
|
||||
ma_waveform_read_pcm_frames(&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'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->playback.channels == DEVICE_CHANNELS);
|
||||
|
||||
/*
|
||||
<span style="color:#009900">/*
|
||||
The first thing to do is check if there's enough data available in the ring buffer. If so we can read from it. Otherwise we need to keep filling
|
||||
the ring buffer until there's enough, making sure we only fill the ring buffer in chunks of PCM_FRAME_CHUNK_SIZE.
|
||||
*/
|
||||
while (pcmFramesProcessed < frameCount) { /* Keep going until we've filled the output buffer. */
|
||||
ma_uint32 framesRemaining = frameCount - pcmFramesProcessed;
|
||||
*/</span>
|
||||
<span style="color:#0033ff">while</span> (pcmFramesProcessed < frameCount) { <span style="color:#009900">/* Keep going until we've filled the output buffer. */</span>
|
||||
<span style="color:#0099cc">ma_uint32</span> framesRemaining = frameCount - pcmFramesProcessed;
|
||||
|
||||
pcmFramesAvailableInRB = ma_pcm_rb_available_read(&g_rb);
|
||||
if (pcmFramesAvailableInRB > 0) {
|
||||
ma_uint32 framesToRead = (framesRemaining < pcmFramesAvailableInRB) ? framesRemaining : pcmFramesAvailableInRB;
|
||||
void* pReadBuffer;
|
||||
<span style="color:#0033ff">if</span> (pcmFramesAvailableInRB > 0) {
|
||||
<span style="color:#0099cc">ma_uint32</span> framesToRead = (framesRemaining < pcmFramesAvailableInRB) ? framesRemaining : pcmFramesAvailableInRB;
|
||||
<span style="color:#0033ff">void</span>* pReadBuffer;
|
||||
|
||||
ma_pcm_rb_acquire_read(&g_rb, &framesToRead, &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->playback.format, pDevice->playback.channels);
|
||||
pcmFramesProcessed += framesToRead;
|
||||
} else {
|
||||
/*
|
||||
} <span style="color:#0033ff">else</span> {
|
||||
<span style="color:#009900">/*
|
||||
There's nothing in the buffer. Fill it with more data from the callback. We reset the buffer first so that the read and write pointers
|
||||
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(&g_rb);
|
||||
ma_pcm_rb_acquire_write(&g_rb, &framesToWrite, &pWriteBuffer);
|
||||
{
|
||||
MA_ASSERT(framesToWrite == PCM_FRAME_CHUNK_SIZE); /* <-- 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">/* <-- 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(&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(&waveformConfig, &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; /* <-- Set this to a pointer to the ring buffer if you don't want it in global scope. */
|
||||
deviceConfig.pUserData = NULL; <span style="color:#009900">/* <-- Set this to a pointer to the ring buffer if you don't want it in global scope. */</span>
|
||||
|
||||
if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
|
||||
printf("Failed to open playback device.\n");
|
||||
<span style="color:#0033ff">if</span> (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
|
||||
printf(<span style="color:#cc3300">"Failed to open playback device.\n"</span>);
|
||||
ma_pcm_rb_uninit(&g_rb);
|
||||
return -4;
|
||||
<span style="color:#0033ff">return</span> -4;
|
||||
}
|
||||
|
||||
printf("Device Name: %s\n", device.playback.name);
|
||||
printf(<span style="color:#cc3300">"Device Name: %s\n"</span>, device.playback.name);
|
||||
|
||||
if (ma_device_start(&device) != MA_SUCCESS) {
|
||||
printf("Failed to start playback device.\n");
|
||||
<span style="color:#0033ff">if</span> (ma_device_start(&device) != MA_SUCCESS) {
|
||||
printf(<span style="color:#cc3300">"Failed to start playback device.\n"</span>);
|
||||
ma_pcm_rb_uninit(&g_rb);
|
||||
ma_device_uninit(&device);
|
||||
return -5;
|
||||
<span style="color:#0033ff">return</span> -5;
|
||||
}
|
||||
|
||||
printf("Press Enter to quit...\n");
|
||||
printf(<span style="color:#cc3300">"Press Enter to quit...\n"</span>);
|
||||
getchar();
|
||||
|
||||
ma_device_uninit(&device);
|
||||
ma_pcm_rb_uninit(&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>
|
||||
|
||||
@@ -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 "../miniaudio.h"
|
||||
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300">"../miniaudio.h"</span>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300"><stdlib.h></span>
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300"><stdio.h></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->pUserData;
|
||||
<span style="color:#0099cc">ma_encoder</span>* pEncoder = (<span style="color:#0099cc">ma_encoder</span>*)pDevice->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 < 2) {
|
||||
printf("No input file.\n");
|
||||
return -1;
|
||||
<span style="color:#0033ff">if</span> (argc < 2) {
|
||||
printf(<span style="color:#cc3300">"No input file.\n"</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], &encoderConfig, &encoder) != MA_SUCCESS) {
|
||||
printf("Failed to initialize output file.\n");
|
||||
return -1;
|
||||
<span style="color:#0033ff">if</span> (ma_encoder_init_file(argv[1], &encoderConfig, &encoder) != MA_SUCCESS) {
|
||||
printf(<span style="color:#cc3300">"Failed to initialize output file.\n"</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 = &encoder;
|
||||
|
||||
result = ma_device_init(NULL, &deviceConfig, &device);
|
||||
if (result != MA_SUCCESS) {
|
||||
printf("Failed to initialize capture device.\n");
|
||||
return -2;
|
||||
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
|
||||
printf(<span style="color:#cc3300">"Failed to initialize capture device.\n"</span>);
|
||||
<span style="color:#0033ff">return</span> -2;
|
||||
}
|
||||
|
||||
result = ma_device_start(&device);
|
||||
if (result != MA_SUCCESS) {
|
||||
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
|
||||
ma_device_uninit(&device);
|
||||
printf("Failed to start device.\n");
|
||||
return -3;
|
||||
printf(<span style="color:#cc3300">"Failed to start device.\n"</span>);
|
||||
<span style="color:#0033ff">return</span> -3;
|
||||
}
|
||||
|
||||
printf("Press Enter to stop recording...\n");
|
||||
printf(<span style="color:#cc3300">"Press Enter to stop recording...\n"</span>);
|
||||
getchar();
|
||||
|
||||
ma_device_uninit(&device);
|
||||
ma_encoder_uninit(&encoder);
|
||||
|
||||
return 0;
|
||||
<span style="color:#0033ff">return</span> 0;
|
||||
}
|
||||
</pre></div></td>
|
||||
</tr></table>
|
||||
|
||||
@@ -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 "../miniaudio.h"
|
||||
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300">"../miniaudio.h"</span>
|
||||
|
||||
#include <stdio.h>
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300"><stdio.h></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->capture.format == pDevice->playback.format);
|
||||
MA_ASSERT(pDevice->capture.channels == pDevice->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->capture.format, pDevice->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, &deviceConfig, &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(&device);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
<span style="color:#666666">#ifdef</span> __EMSCRIPTEN__
|
||||
emscripten_set_main_loop(main_loop__em, 0, 1);
|
||||
#else
|
||||
printf("Press Enter to quit...\n");
|
||||
<span style="color:#666666">#else</span>
|
||||
printf(<span style="color:#cc3300">"Press Enter to quit...\n"</span>);
|
||||
getchar();
|
||||
#endif
|
||||
<span style="color:#666666">#endif</span>
|
||||
|
||||
ma_device_uninit(&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>
|
||||
|
||||
@@ -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 "../miniaudio.h"
|
||||
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300">"../miniaudio.h"</span>
|
||||
|
||||
#include <stdio.h>
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300"><stdio.h></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, &context) != MA_SUCCESS) {
|
||||
printf("Failed to initialize context.\n");
|
||||
return -2;
|
||||
<span style="color:#0033ff">if</span> (ma_context_init(NULL, 0, NULL, &context) != MA_SUCCESS) {
|
||||
printf(<span style="color:#cc3300">"Failed to initialize context.\n"</span>);
|
||||
<span style="color:#0033ff">return</span> -2;
|
||||
}
|
||||
|
||||
result = ma_context_get_devices(&context, &pPlaybackDeviceInfos, &playbackDeviceCount, &pCaptureDeviceInfos, &captureDeviceCount);
|
||||
if (result != MA_SUCCESS) {
|
||||
printf("Failed to retrieve device information.\n");
|
||||
return -3;
|
||||
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
|
||||
printf(<span style="color:#cc3300">"Failed to retrieve device information.\n"</span>);
|
||||
<span style="color:#0033ff">return</span> -3;
|
||||
}
|
||||
|
||||
printf("Playback Devices\n");
|
||||
for (iDevice = 0; iDevice < playbackDeviceCount; ++iDevice) {
|
||||
printf(" %u: %s\n", iDevice, pPlaybackDeviceInfos[iDevice].name);
|
||||
printf(<span style="color:#cc3300">"Playback Devices\n"</span>);
|
||||
<span style="color:#0033ff">for</span> (iDevice = 0; iDevice < playbackDeviceCount; ++iDevice) {
|
||||
printf(<span style="color:#cc3300">" %u: %s\n"</span>, iDevice, pPlaybackDeviceInfos[iDevice].name);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
printf(<span style="color:#cc3300">"\n"</span>);
|
||||
|
||||
printf("Capture Devices\n");
|
||||
for (iDevice = 0; iDevice < captureDeviceCount; ++iDevice) {
|
||||
printf(" %u: %s\n", iDevice, pCaptureDeviceInfos[iDevice].name);
|
||||
printf(<span style="color:#cc3300">"Capture Devices\n"</span>);
|
||||
<span style="color:#0033ff">for</span> (iDevice = 0; iDevice < captureDeviceCount; ++iDevice) {
|
||||
printf(<span style="color:#cc3300">" %u: %s\n"</span>, iDevice, pCaptureDeviceInfos[iDevice].name);
|
||||
}
|
||||
|
||||
|
||||
ma_context_uninit(&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>
|
||||
|
||||
@@ -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 "../miniaudio.h"
|
||||
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300">"../miniaudio.h"</span>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300"><stdlib.h></span>
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300"><stdio.h></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->pUserData;
|
||||
<span style="color:#0099cc">ma_encoder</span>* pEncoder = (<span style="color:#0099cc">ma_encoder</span>*)pDevice->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 < 2) {
|
||||
printf("No input file.\n");
|
||||
return -1;
|
||||
<span style="color:#0033ff">if</span> (argc < 2) {
|
||||
printf(<span style="color:#cc3300">"No input file.\n"</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], &encoderConfig, &encoder) != MA_SUCCESS) {
|
||||
printf("Failed to initialize output file.\n");
|
||||
return -1;
|
||||
<span style="color:#0033ff">if</span> (ma_encoder_init_file(argv[1], &encoderConfig, &encoder) != MA_SUCCESS) {
|
||||
printf(<span style="color:#cc3300">"Failed to initialize output file.\n"</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 = &encoder;
|
||||
|
||||
result = ma_device_init_ex(backends, sizeof(backends)/sizeof(backends[0]), NULL, &deviceConfig, &device);
|
||||
if (result != MA_SUCCESS) {
|
||||
printf("Failed to initialize loopback device.\n");
|
||||
return -2;
|
||||
result = ma_device_init_ex(backends, <span style="color:#0033ff">sizeof</span>(backends)/<span style="color:#0033ff">sizeof</span>(backends[0]), NULL, &deviceConfig, &device);
|
||||
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
|
||||
printf(<span style="color:#cc3300">"Failed to initialize loopback device.\n"</span>);
|
||||
<span style="color:#0033ff">return</span> -2;
|
||||
}
|
||||
|
||||
result = ma_device_start(&device);
|
||||
if (result != MA_SUCCESS) {
|
||||
<span style="color:#0033ff">if</span> (result != MA_SUCCESS) {
|
||||
ma_device_uninit(&device);
|
||||
printf("Failed to start device.\n");
|
||||
return -3;
|
||||
printf(<span style="color:#cc3300">"Failed to start device.\n"</span>);
|
||||
<span style="color:#0033ff">return</span> -3;
|
||||
}
|
||||
|
||||
printf("Press Enter to stop recording...\n");
|
||||
printf(<span style="color:#cc3300">"Press Enter to stop recording...\n"</span>);
|
||||
getchar();
|
||||
|
||||
ma_device_uninit(&device);
|
||||
ma_encoder_uninit(&encoder);
|
||||
|
||||
return 0;
|
||||
<span style="color:#0033ff">return</span> 0;
|
||||
}
|
||||
</pre></div></td>
|
||||
</tr></table>
|
||||
|
||||
@@ -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 "../miniaudio.h"
|
||||
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300">"../miniaudio.h"</span>
|
||||
|
||||
#include <stdio.h>
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300"><stdio.h></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->pUserData;
|
||||
if (pDecoder == NULL) {
|
||||
return;
|
||||
<span style="color:#0099cc">ma_decoder</span>* pDecoder = (<span style="color:#0099cc">ma_decoder</span>*)pDevice->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 "loop" 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 < 2) {
|
||||
printf("No input file.\n");
|
||||
return -1;
|
||||
<span style="color:#0033ff">if</span> (argc < 2) {
|
||||
printf(<span style="color:#cc3300">"No input file.\n"</span>);
|
||||
<span style="color:#0033ff">return</span> -1;
|
||||
}
|
||||
|
||||
result = ma_decoder_init_file(argv[1], NULL, &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 = &decoder;
|
||||
|
||||
if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
|
||||
printf("Failed to open playback device.\n");
|
||||
<span style="color:#0033ff">if</span> (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
|
||||
printf(<span style="color:#cc3300">"Failed to open playback device.\n"</span>);
|
||||
ma_decoder_uninit(&decoder);
|
||||
return -3;
|
||||
<span style="color:#0033ff">return</span> -3;
|
||||
}
|
||||
|
||||
if (ma_device_start(&device) != MA_SUCCESS) {
|
||||
printf("Failed to start playback device.\n");
|
||||
<span style="color:#0033ff">if</span> (ma_device_start(&device) != MA_SUCCESS) {
|
||||
printf(<span style="color:#cc3300">"Failed to start playback device.\n"</span>);
|
||||
ma_device_uninit(&device);
|
||||
ma_decoder_uninit(&decoder);
|
||||
return -4;
|
||||
<span style="color:#0033ff">return</span> -4;
|
||||
}
|
||||
|
||||
printf("Press Enter to quit...");
|
||||
printf(<span style="color:#cc3300">"Press Enter to quit..."</span>);
|
||||
getchar();
|
||||
|
||||
ma_device_uninit(&device);
|
||||
ma_decoder_uninit(&decoder);
|
||||
|
||||
return 0;
|
||||
<span style="color:#0033ff">return</span> 0;
|
||||
}
|
||||
</pre></div></td>
|
||||
</tr></table>
|
||||
|
||||
@@ -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 "../miniaudio.h"
|
||||
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300">"../miniaudio.h"</span>
|
||||
|
||||
#include <stdio.h>
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300"><stdio.h></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; /* <-- Signaled by the audio thread, waited on by the main thread. */
|
||||
<span style="color:#0099cc">ma_event</span> g_stopEvent; <span style="color:#009900">/* <-- 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 < 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 < 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'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 < frameCount) {
|
||||
ma_uint32 iSample;
|
||||
ma_uint32 framesReadThisIteration;
|
||||
ma_uint32 totalFramesRemaining = frameCount - totalFramesRead;
|
||||
ma_uint32 framesToReadThisIteration = tempCapInFrames;
|
||||
if (framesToReadThisIteration > totalFramesRemaining) {
|
||||
<span style="color:#0033ff">while</span> (totalFramesRead < 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 > 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 < framesReadThisIteration*CHANNEL_COUNT; ++iSample) {
|
||||
<span style="color:#009900">/* Mix the frames together. */</span>
|
||||
<span style="color:#0033ff">for</span> (iSample = 0; iSample < framesReadThisIteration*CHANNEL_COUNT; ++iSample) {
|
||||
pOutputF32[totalFramesRead*CHANNEL_COUNT + iSample] += temp[iSample];
|
||||
}
|
||||
|
||||
totalFramesRead += framesReadThisIteration;
|
||||
|
||||
if (framesReadThisIteration < framesToReadThisIteration) {
|
||||
break; /* Reached EOF. */
|
||||
<span style="color:#0033ff">if</span> (framesReadThisIteration < 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->playback.format == SAMPLE_FORMAT); /* <-- Important for this example. */
|
||||
MA_ASSERT(pDevice->playback.format == SAMPLE_FORMAT); <span style="color:#009900">/* <-- Important for this example. */</span>
|
||||
|
||||
for (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
|
||||
if (!g_pDecodersAtEnd[iDecoder]) {
|
||||
ma_uint32 framesRead = read_and_mix_pcm_frames_f32(&g_pDecoders[iDecoder], pOutputF32, frameCount);
|
||||
if (framesRead < frameCount) {
|
||||
<span style="color:#0033ff">for</span> (iDecoder = 0; iDecoder < 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(&g_pDecoders[iDecoder], pOutputF32, frameCount);
|
||||
<span style="color:#0033ff">if</span> (framesRead < 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'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(&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 < 2) {
|
||||
printf("No input files.\n");
|
||||
return -1;
|
||||
<span style="color:#0033ff">if</span> (argc < 2) {
|
||||
printf(<span style="color:#cc3300">"No input files.\n"</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 < g_decoderCount; ++iDecoder) {
|
||||
<span style="color:#0033ff">for</span> (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
|
||||
result = ma_decoder_init_file(argv[1+iDecoder], &decoderConfig, &g_pDecoders[iDecoder]);
|
||||
if (result != MA_SUCCESS) {
|
||||
ma_uint32 iDecoder2;
|
||||
for (iDecoder2 = 0; iDecoder2 < 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 < iDecoder; ++iDecoder2) {
|
||||
ma_decoder_uninit(&g_pDecoders[iDecoder2]);
|
||||
}
|
||||
free(g_pDecoders);
|
||||
free(g_pDecodersAtEnd);
|
||||
|
||||
printf("Failed to load %s.\n", argv[1+iDecoder]);
|
||||
return -3;
|
||||
printf(<span style="color:#cc3300">"Failed to load %s.\n"</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, &deviceConfig, &device) != MA_SUCCESS) {
|
||||
for (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
|
||||
<span style="color:#0033ff">if</span> (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
|
||||
<span style="color:#0033ff">for</span> (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
|
||||
ma_decoder_uninit(&g_pDecoders[iDecoder]);
|
||||
}
|
||||
free(g_pDecoders);
|
||||
free(g_pDecodersAtEnd);
|
||||
|
||||
printf("Failed to open playback device.\n");
|
||||
return -3;
|
||||
printf(<span style="color:#cc3300">"Failed to open playback device.\n"</span>);
|
||||
<span style="color:#0033ff">return</span> -3;
|
||||
}
|
||||
|
||||
/*
|
||||
<span style="color:#009900">/*
|
||||
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
|
||||
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't need to do that for this example.
|
||||
*/
|
||||
*/</span>
|
||||
ma_event_init(&g_stopEvent);
|
||||
|
||||
/* Now we start playback and wait for the audio thread to tell us to stop. */
|
||||
if (ma_device_start(&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(&device) != MA_SUCCESS) {
|
||||
ma_device_uninit(&device);
|
||||
for (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
|
||||
<span style="color:#0033ff">for</span> (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
|
||||
ma_decoder_uninit(&g_pDecoders[iDecoder]);
|
||||
}
|
||||
free(g_pDecoders);
|
||||
free(g_pDecodersAtEnd);
|
||||
|
||||
printf("Failed to start playback device.\n");
|
||||
return -4;
|
||||
printf(<span style="color:#cc3300">"Failed to start playback device.\n"</span>);
|
||||
<span style="color:#0033ff">return</span> -4;
|
||||
}
|
||||
|
||||
printf("Waiting for playback to complete...\n");
|
||||
printf(<span style="color:#cc3300">"Waiting for playback to complete...\n"</span>);
|
||||
ma_event_wait(&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(&device);
|
||||
|
||||
for (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
|
||||
<span style="color:#0033ff">for</span> (iDecoder = 0; iDecoder < g_decoderCount; ++iDecoder) {
|
||||
ma_decoder_uninit(&g_pDecoders[iDecoder]);
|
||||
}
|
||||
free(g_pDecoders);
|
||||
free(g_pDecodersAtEnd);
|
||||
|
||||
return 0;
|
||||
<span style="color:#0033ff">return</span> 0;
|
||||
}
|
||||
</pre></div></td>
|
||||
</tr></table>
|
||||
|
||||
@@ -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 "../miniaudio.h"
|
||||
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300">"../miniaudio.h"</span>
|
||||
|
||||
#include <stdio.h>
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300"><stdio.h></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->pUserData;
|
||||
if (pDecoder == NULL) {
|
||||
return;
|
||||
<span style="color:#0099cc">ma_decoder</span>* pDecoder = (<span style="color:#0099cc">ma_decoder</span>*)pDevice->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 < 2) {
|
||||
printf("No input file.\n");
|
||||
return -1;
|
||||
<span style="color:#0033ff">if</span> (argc < 2) {
|
||||
printf(<span style="color:#cc3300">"No input file.\n"</span>);
|
||||
<span style="color:#0033ff">return</span> -1;
|
||||
}
|
||||
|
||||
result = ma_decoder_init_file(argv[1], NULL, &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 = &decoder;
|
||||
|
||||
if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
|
||||
printf("Failed to open playback device.\n");
|
||||
<span style="color:#0033ff">if</span> (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
|
||||
printf(<span style="color:#cc3300">"Failed to open playback device.\n"</span>);
|
||||
ma_decoder_uninit(&decoder);
|
||||
return -3;
|
||||
<span style="color:#0033ff">return</span> -3;
|
||||
}
|
||||
|
||||
if (ma_device_start(&device) != MA_SUCCESS) {
|
||||
printf("Failed to start playback device.\n");
|
||||
<span style="color:#0033ff">if</span> (ma_device_start(&device) != MA_SUCCESS) {
|
||||
printf(<span style="color:#cc3300">"Failed to start playback device.\n"</span>);
|
||||
ma_device_uninit(&device);
|
||||
ma_decoder_uninit(&decoder);
|
||||
return -4;
|
||||
<span style="color:#0033ff">return</span> -4;
|
||||
}
|
||||
|
||||
printf("Press Enter to quit...");
|
||||
printf(<span style="color:#cc3300">"Press Enter to quit..."</span>);
|
||||
getchar();
|
||||
|
||||
ma_device_uninit(&device);
|
||||
ma_decoder_uninit(&decoder);
|
||||
|
||||
return 0;
|
||||
<span style="color:#0033ff">return</span> 0;
|
||||
}
|
||||
</pre></div></td>
|
||||
</tr></table>
|
||||
|
||||
@@ -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 "../miniaudio.h"
|
||||
<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">"../miniaudio.h"</span>
|
||||
|
||||
#include <stdio.h>
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300"><stdio.h></span>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
<span style="color:#666666">#ifdef</span> __EMSCRIPTEN__
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300"><emscripten.h></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->playback.channels == DEVICE_CHANNELS);
|
||||
|
||||
pSineWave = (ma_waveform*)pDevice->pUserData;
|
||||
pSineWave = (<span style="color:#0099cc">ma_waveform</span>*)pDevice->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(&sineWaveConfig, &sineWave);
|
||||
@@ -313,31 +313,31 @@ int main(int argc, char** argv)
|
||||
deviceConfig.dataCallback = data_callback;
|
||||
deviceConfig.pUserData = &sineWave;
|
||||
|
||||
if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
|
||||
printf("Failed to open playback device.\n");
|
||||
return -4;
|
||||
<span style="color:#0033ff">if</span> (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
|
||||
printf(<span style="color:#cc3300">"Failed to open playback device.\n"</span>);
|
||||
<span style="color:#0033ff">return</span> -4;
|
||||
}
|
||||
|
||||
printf("Device Name: %s\n", device.playback.name);
|
||||
printf(<span style="color:#cc3300">"Device Name: %s\n"</span>, device.playback.name);
|
||||
|
||||
if (ma_device_start(&device) != MA_SUCCESS) {
|
||||
printf("Failed to start playback device.\n");
|
||||
<span style="color:#0033ff">if</span> (ma_device_start(&device) != MA_SUCCESS) {
|
||||
printf(<span style="color:#cc3300">"Failed to start playback device.\n"</span>);
|
||||
ma_device_uninit(&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("Press Enter to quit...\n");
|
||||
<span style="color:#666666">#else</span>
|
||||
printf(<span style="color:#cc3300">"Press Enter to quit...\n"</span>);
|
||||
getchar();
|
||||
#endif
|
||||
<span style="color:#666666">#endif</span>
|
||||
|
||||
ma_device_uninit(&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
@@ -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 "miniaudio.h"
|
||||
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300">"miniaudio.h"</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, &config, &device) != MA_SUCCESS) {
|
||||
<span style="color:#0099cc">ma_device</span> device;
|
||||
<span style="color:#0033ff">if</span> (ma_device_init(NULL, &config, &device) != MA_SUCCESS) {
|
||||
... An error occurred ...
|
||||
}
|
||||
|
||||
ma_device_start(&device); // The device is sleeping by default so you'll need to start it manually.
|
||||
ma_device_start(&device); <span style="color:#009900">// The device is sleeping by default so you'll need to start it manually.</span>
|
||||
|
||||
...
|
||||
|
||||
ma_device_uninit(&device); // This will stop the device so no need to do that manually.
|
||||
ma_device_uninit(&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 "context". 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, &context) != MA_SUCCESS) {
|
||||
// Error.
|
||||
<span style="color:#0099cc">ma_context</span> context;
|
||||
<span style="color:#0033ff">if</span> (ma_context_init(NULL, 0, NULL, &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(&context, &pPlaybackDeviceInfos, &playbackDeviceCount, &pCaptureDeviceInfos, &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(&context, &pPlaybackDeviceInfos, &playbackDeviceCount, &pCaptureDeviceInfos, &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'd prefer.
|
||||
for (ma_uint32 iDevice = 0; iDevice < playbackDeviceCount; iDevice += 1) {
|
||||
printf("%d - %s\n", 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'd prefer.</span>
|
||||
<span style="color:#0033ff">for</span> (<span style="color:#0099cc">ma_uint32</span> iDevice = 0; iDevice < playbackDeviceCount; iDevice += 1) {
|
||||
printf(<span style="color:#cc3300">"%d - %s\n"</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 = &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(&context, &config, &device) != MA_SUCCESS) {
|
||||
// Error
|
||||
<span style="color:#0099cc">ma_device</span> device;
|
||||
<span style="color:#0033ff">if</span> (ma_device_init(&context, &config, &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 "extras/stb_vorbis.c" // Enables Vorbis decoding.
|
||||
<span style="color:#666666">#define</span> STB_VORBIS_HEADER_ONLY
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300">"extras/stb_vorbis.c"</span> <span style="color:#009900">// Enables Vorbis decoding.</span>
|
||||
|
||||
#define MINIAUDIO_IMPLEMENTATION
|
||||
#include "miniaudio.h"
|
||||
<span style="color:#666666">#define</span> MINIAUDIO_IMPLEMENTATION
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300">"miniaudio.h"</span>
|
||||
|
||||
// The stb_vorbis implementation must come after the implementation of miniaudio.
|
||||
#undef STB_VORBIS_HEADER_ONLY
|
||||
#include "extras/stb_vorbis.c"
|
||||
<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">"extras/stb_vorbis.c"</span>
|
||||
</pre></div><p>
|
||||
|
||||
A copy of stb_vorbis is included in the "extras" 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("MySong.mp3", NULL, &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">"MySong.mp3"</span>, NULL, &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'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 < 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 < 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("my_file.wav", &config, &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">"my_file.wav"</span>, &config, &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(&config, &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(&converter, pFramesOut, pFramesIn, frameCount);
|
||||
if (result != MA_SUCCESS) {
|
||||
// Error.
|
||||
<span style="color:#0099cc">ma_result</span> result = ma_channel_converter_process_pcm_frames(&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(&config, &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(&config, &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(&resampler, pFramesIn, &frameCountIn, pFramesOut, &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(&resampler, pFramesIn, &frameCountIn, pFramesOut, &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 "extras/speex_resampler/ma_speex_resampler.h"
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300">"extras/speex_resampler/ma_speex_resampler.h"</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 "extras/speex_resampler/ma_speex_resampler.h"
|
||||
<span style="color:#666666">#define</span> MINIAUDIO_SPEEX_RESAMPLER_IMPLEMENTATION
|
||||
<span style="color:#666666">#include</span> <span style="color:#cc3300">"extras/speex_resampler/ma_speex_resampler.h"</span>
|
||||
</pre></div><p>
|
||||
|
||||
Note that even if you opt-in to the Speex backend, miniaudio won'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(&config, &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(&config, &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(&converter, pFramesIn, &frameCountIn, pFramesOut, &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(&converter, pFramesIn, &frameCountIn, pFramesOut, &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(&config, &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(&config, &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(&config, &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(&config, &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 < filterCount; iFilter += 1) {
|
||||
<span style="color:#0033ff">for</span> (iFilter = 0; iFilter < filterCount; iFilter += 1) {
|
||||
ma_lpf2_process_pcm_frames(&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(&config, &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(&config, &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(&config, &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(&config, &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, &allocationCallbacks);
|
||||
ma_audio_buffer buffer;
|
||||
<span style="color:#0099cc">ma_audio_buffer_config</span> config = ma_audio_buffer_config_init(format, channels, sizeInFrames, pExistingData, &allocationCallbacks);
|
||||
<span style="color:#0099cc">ma_audio_buffer</span> buffer;
|
||||
result = ma_audio_buffer_init(&config, &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, &allocationCallbacks);
|
||||
ma_audio_buffer* pBuffer
|
||||
<span style="color:#0099cc">ma_audio_buffer_config</span> config = ma_audio_buffer_config_init(format, channels, sizeInFrames, pExistingData, &allocationCallbacks);
|
||||
<span style="color:#0099cc">ma_audio_buffer</span>* pBuffer
|
||||
result = ma_audio_buffer_alloc_and_init(&config, &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 < 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 < 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, &pMappedFrames, &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, &pMappedFrames, &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->format, pAudioBuffer->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, &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, &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's ma
|
||||
<Package ...>
|
||||
...
|
||||
<Capabilities>
|
||||
<DeviceCapability Name="microphone" />
|
||||
<DeviceCapability Name=<span style="color:#cc3300">"microphone"</span> />
|
||||
</Capabilities>
|
||||
</Package>
|
||||
</pre></div><p>
|
||||
|
||||
Reference in New Issue
Block a user