diff --git a/docs/examples/custom_backend.html b/docs/examples/custom_backend.html index 108698f9..6dd0d27a 100644 --- a/docs/examples/custom_backend.html +++ b/docs/examples/custom_backend.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Custom Backend

This example show how a custom backend can be implemented.

diff --git a/docs/examples/custom_decoder.html b/docs/examples/custom_decoder.html index 8c2d5400..e619f6ef 100644 --- a/docs/examples/custom_decoder.html +++ b/docs/examples/custom_decoder.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Custom Decoder

Demonstrates how to implement a custom decoder.

diff --git a/docs/examples/custom_decoder_engine.html b/docs/examples/custom_decoder_engine.html index e1567c49..7a8538fb 100644 --- a/docs/examples/custom_decoder_engine.html +++ b/docs/examples/custom_decoder_engine.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Custom Decoder Engine

Demonstrates how to implement a custom decoder and use it with the high level API.

diff --git a/docs/examples/data_source_chaining.html b/docs/examples/data_source_chaining.html index 28572bd1..413f5205 100644 --- a/docs/examples/data_source_chaining.html +++ b/docs/examples/data_source_chaining.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Data Source Chaining

Demonstrates one way to chain together a number of data sources so they play back seamlessly without gaps. diff --git a/docs/examples/duplex_effect.html b/docs/examples/duplex_effect.html index 494257f1..a48a7bbb 100644 --- a/docs/examples/duplex_effect.html +++ b/docs/examples/duplex_effect.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {

+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Duplex Effect

Demonstrates how to apply an effect to a duplex stream using the node graph system.

diff --git a/docs/examples/engine_advanced.html b/docs/examples/engine_advanced.html index 576403cc..3f167fd2 100644 --- a/docs/examples/engine_advanced.html +++ b/docs/examples/engine_advanced.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Engine Advanced

This example demonstrates some of the advanced features of the high level engine API.

diff --git a/docs/examples/engine_effects.html b/docs/examples/engine_effects.html index 4f4a16d1..1a48bc67 100644 --- a/docs/examples/engine_effects.html +++ b/docs/examples/engine_effects.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Engine Effects

Demonstrates how to apply an effect to sounds using the high level engine API.

diff --git a/docs/examples/engine_hello_world.html b/docs/examples/engine_hello_world.html index 4900aa84..4890a2bc 100644 --- a/docs/examples/engine_hello_world.html +++ b/docs/examples/engine_hello_world.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Engine Hello World

This example demonstrates how to initialize an audio engine and play a sound.

diff --git a/docs/examples/engine_sdl.html b/docs/examples/engine_sdl.html new file mode 100644 index 00000000..a02de196 --- /dev/null +++ b/docs/examples/engine_sdl.html @@ -0,0 +1,402 @@ + + + + miniaudio - A single file audio playback and capture library. + + + + + + + + + + + + +
+
+ + + + + + + + + +
+
+
+ + +
+

Engine Sdl

+Shows how to use the high level engine API with SDL. +

+

+ +By default, miniaudio's engine API will initialize a device internally for audio output. You can +instead use the engine independently of a device. To show this off, this example will use SDL for +audio output instead of miniaudio. +

+

+ +This example will load the sound specified on the command line and rotate it around the listener's +head.

+
+#define MA_NO_DEVICE_IO /* <-- Disables the ma_device API. We don't need that in this example since SDL will be doing that part for us. */
+#define MINIAUDIO_IMPLEMENTATION
+#include "../miniaudio.h"
+
+#define SDL_MAIN_HANDLED
+#include <SDL.h>    /* Change this to your include location. Might be <SDL2/SDL.h>. */
+
+#define CHANNELS    2               /* Must be stereo for this example. */
+#define SAMPLE_RATE 48000
+
+static ma_engine g_engine;
+static ma_sound g_sound;            /* This example will play only a single sound at once, so we only need one ma_sound object. */
+
+void data_callback(void* pUserData, ma_uint8* pBuffer, int bufferSizeInBytes)
+{
+    /* Reading is just a matter of reading straight from the engine. */
+    ma_uint32 bufferSizeInFrames = (ma_uint32)bufferSizeInBytes / ma_get_bytes_per_frame(ma_format_f32, ma_engine_get_channels(&g_engine));
+    ma_engine_read_pcm_frames(&g_engine, pBuffer, bufferSizeInFrames, NULL);
+}
+
+int main(int argc, char** argv)
+{
+    ma_result result;
+    ma_engine_config engineConfig;
+    SDL_AudioSpec desiredSpec;
+    SDL_AudioSpec obtainedSpec;
+    SDL_AudioDeviceID deviceID;
+
+    if (argc < 2) {
+        printf("No input file.");
+        return -1;
+    }
+
+    /*
+    We'll initialize the engine first for the purpose of the example, but since the engine and SDL
+    are independent of each other you can initialize them in any order. You need only make sure the
+    channel count and sample rates are consistent between the two.
+
+    When initializing the engine it's important to make sure we don't initialize a device
+    internally because we want SDL to be dealing with that for us instead.
+    */
+    engineConfig = ma_engine_config_init();
+    engineConfig.noDevice   = MA_TRUE;      /* <-- Make sure this is set so that no device is created (we'll deal with that ourselves). */
+    engineConfig.channels   = CHANNELS;
+    engineConfig.sampleRate = SAMPLE_RATE;
+
+    result = ma_engine_init(&engineConfig, &g_engine);
+    if (result != MA_SUCCESS) {
+        printf("Failed to initialize audio engine.");
+        return -1;
+    }
+
+    /* Now load our sound. */
+    result = ma_sound_init_from_file(&g_engine, argv[1], 0, NULL, NULL, &g_sound);
+    if (result != MA_SUCCESS) {
+        printf("Failed to initialize sound.");
+        return -1;
+    }
+
+    /* Loop the sound so we can continuously hear it. */
+    ma_sound_set_looping(&g_sound, MA_TRUE);
+
+    /*
+    The sound will not be started by default, so start it now. We won't hear anything until the SDL
+    audio device has been opened and started.
+    */
+    ma_sound_start(&g_sound);
+
+
+    /*
+    Now that we have the engine and sound we can initialize SDL. This could have also been done
+    first before the engine and sound.
+    */
+    if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0) {
+        printf("Failed to initialize SDL sub-system.");
+        return -1;
+    }
+
+    MA_ZERO_OBJECT(&desiredSpec);
+    desiredSpec.freq     = ma_engine_get_sample_rate(&g_engine);
+    desiredSpec.format   = AUDIO_F32;
+    desiredSpec.channels = ma_engine_get_channels(&g_engine);
+    desiredSpec.samples  = 512;
+    desiredSpec.callback = data_callback;
+    desiredSpec.userdata = NULL;
+
+    deviceID = SDL_OpenAudioDevice(NULL, 0, &desiredSpec, &obtainedSpec, SDL_AUDIO_ALLOW_ANY_CHANGE);
+    if (deviceID == 0) {
+        printf("Failed to open SDL audio device.");
+        return -1;
+    }
+
+    /* Start playback. */
+    SDL_PauseAudioDevice(deviceID, 0);
+
+#if 1
+    {
+        /* We'll move the sound around the listener which we'll leave at the origin. */
+        float stepAngle = 0.002f;
+        float angle = 0;
+        float distance = 2;
+
+        for (;;) {
+            double x = ma_cosd(angle) - ma_sind(angle);
+            double y = ma_sind(angle) + ma_cosd(angle);
+
+            ma_sound_set_position(&g_sound, (float)x * distance, 0, (float)y * distance);
+
+            angle += stepAngle;
+            ma_sleep(1);
+        }
+    }
+#else
+    printf("Press Enter to quit...");
+    getchar();
+#endif
+
+    ma_sound_uninit(&g_sound);
+    ma_engine_uninit(&g_engine);
+    SDL_CloseAudioDevice(deviceID);
+    SDL_QuitSubSystem(SDL_INIT_AUDIO);
+
+    return 0;
+}
+
+ + + + + + +
+ +
+ Copyright © 2022 David Reid
+ Developed by David Reid - mackron@gmail.com +
+ + diff --git a/docs/examples/engine_steamaudio.html b/docs/examples/engine_steamaudio.html index 9c1c6007..0a00d981 100644 --- a/docs/examples/engine_steamaudio.html +++ b/docs/examples/engine_steamaudio.html @@ -245,25 +245,40 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Engine Steamaudio

Demonstrates integration of Steam Audio with miniaudio's engine API.

-In this example we'll apply a HRTF effect from Steam Audio. To do this a custom node will be +In this example a HRTF effect from Steam Audio will be applied. To do this a custom node will be implemented which uses Steam Audio's IPLBinauralEffect and IPLHRTF objects.

By implementing this as a node, it can be plugged into any position within the graph. The output -channel count of this node is always stereo.

+channel count of this node is always stereo. +

+

+ +Steam Audio requires fixed sized processing, the size of which must be specified at initialization +time of the IPLBinauralEffect and IPLHRTF objects. This creates a problem because the node graph +will at times need to break down processing into smaller chunks for it's internal processing. The +node graph internally will read into a temporary buffer which is then mixed into the final output +buffer. This temporary buffer is allocated on the stack and is a fixed size. However, variability +comes into play because the channel count of the node is variable. It's not safe to just blindly +process the effect with the frame count specified in miniaudio's node processing callback. Doing so +results in glitching. To work around this, this example is just setting the update size to a known +value that works (256). If it's set to something too big it'll exceed miniaudio's processing size +used by the node graph. Alternatively you could use some kind of intermediary cache which +accumulates input data until enough is available and then do the processing. Ideally, Steam Audio +would support variable sized updates which would avoid this whole mess entirely.

 #define MINIAUDIO_IMPLEMENTATION
 #include "../miniaudio.h"
 
 #include <phonon.h> /* Steam Audio */
-#include <stdint.h> /* Required for uint32_t which is used by STEAMAUDIO_VERSION. */
+#include <stdint.h> /* Required for uint32_t which is used by STEAMAUDIO_VERSION. That dependency needs to be removed from Steam Audio - use IPLuint32 or "unsigned int" instead! */
 
 #define FORMAT      ma_format_f32   /* Must be floating point. */
 #define CHANNELS    2               /* Must be stereo for this example. */
@@ -439,17 +454,15 @@ MA_API ma_result ma_steamaudio_binaural_node_
         return result;
     }
 
+    heapSizeInBytes = 0;
+
     /*
     Unfortunately Steam Audio uses deinterleaved buffers for everything so we'll need to use some
     intermediary buffers. We'll allocate one big buffer on the heap and then use offsets. We'll
     use the frame size from the IPLAudioSettings structure as a basis for the size of the buffer.
     */
-    heapSizeInBytes = sizeof(float) * channelsOut * pBinauralNode->iplAudioSettings.frameSize;  /* Output buffer. */
-
-    /* Only need input buffers if we're not using mono input. */
-    if (channelsIn > 1) {
-        heapSizeInBytes += sizeof(float) * channelsIn * pBinauralNode->iplAudioSettings.frameSize;
-    }
+    heapSizeInBytes += sizeof(float) * channelsOut * pBinauralNode->iplAudioSettings.frameSize; /* Output buffer. */
+    heapSizeInBytes += sizeof(float) * channelsIn  * pBinauralNode->iplAudioSettings.frameSize; /* Input buffer. */
 
     pBinauralNode->_pHeap = ma_malloc(heapSizeInBytes, pAllocationCallbacks);
     if (pBinauralNode->_pHeap == NULL) {
@@ -461,7 +474,7 @@ MA_API ma_result ma_steamaudio_binaural_node_
     pBinauralNode->ppBuffersOut[0] = (float*)pBinauralNode->_pHeap;
     pBinauralNode->ppBuffersOut[1] = (float*)ma_offset_ptr(pBinauralNode->_pHeap, sizeof(float) * pBinauralNode->iplAudioSettings.frameSize);
 
-    if (channelsIn > 1) {
+    {
         ma_uint32 iChannelIn;
         for (iChannelIn = 0; iChannelIn < channelsIn; iChannelIn += 1) {
             pBinauralNode->ppBuffersIn[iChannelIn] = (float*)ma_offset_ptr(pBinauralNode->_pHeap, sizeof(float) * pBinauralNode->iplAudioSettings.frameSize * (channelsOut + iChannelIn));
@@ -547,7 +560,7 @@ MA_API ma_result ma_steamaudio_binaural_node_
     need not be exposed to the public API. There should be no need for the public API to require a
     fixed sized update.
     */
-    iplAudioSettings.frameSize = g_engine.pDevice->playback.internalPeriodSizeInFrames;
+    iplAudioSettings.frameSize = engineConfig.periodSizeInFrames;
 
 
     /* IPLContext */
diff --git a/docs/examples/fixed_size_callback.html b/docs/examples/fixed_size_callback.html
deleted file mode 100644
index a46a32be..00000000
--- a/docs/examples/fixed_size_callback.html
+++ /dev/null
@@ -1,414 +0,0 @@
-
-
-
-    miniaudio - A single file audio playback and capture library.
-    
-	
-    
-    
-
-
-
-
-    
-
-
-
-    
-
- - - - - - - - - -
-
-
- - -
-

Fixed Size Callback

-Shows one way to implement a data callback that is called with a fixed frame count. -

-

- -miniaudio does not have built-in support for firing the data callback with fixed sized buffers. In order to support -this you need to implement a layer that sits on top of the normal data callback. This example demonstrates one way of -doing this. -

-

- -This example uses a ring buffer to act as the intermediary buffer between the low-level device callback and the fixed -sized callback. You do not need to use a ring buffer here, but it's a good opportunity to demonstrate how to use -miniaudio's ring buffer API. The ring buffer in this example is in global scope for simplicity, but you can pass it -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.

-
-#define MINIAUDIO_IMPLEMENTATION
-#include "../miniaudio.h"
-
-#include <stdio.h>
-
-#define DEVICE_FORMAT           ma_format_f32
-#define DEVICE_CHANNELS         1
-#define DEVICE_SAMPLE_RATE      48000
-
-#define PCM_FRAME_CHUNK_SIZE    1234    /* <-- Play around with this to control your fixed sized buffer. */
-
-ma_waveform g_sineWave;
-ma_pcm_rb g_rb; /* The ring buffer. */
-
-void data_callback_fixed(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
-{
-    /*
-    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);
-
-    ma_waveform_read_pcm_frames(&g_sineWave, pOutput, frameCount, NULL);
-
-    /* Unused in this example. */
-    (void)pDevice;
-    (void)pInput;
-}
-
-void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
-{
-    /*
-    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;
-
-    MA_ASSERT(pDevice->playback.channels == DEVICE_CHANNELS);
-
-    /*
-    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;
-
-        pcmFramesAvailableInRB = ma_pcm_rb_available_read(&g_rb);
-        if (pcmFramesAvailableInRB > 0) {
-            ma_uint32 framesToRead = (framesRemaining < pcmFramesAvailableInRB) ? framesRemaining : pcmFramesAvailableInRB;
-            void* pReadBuffer;
-
-            ma_pcm_rb_acquire_read(&g_rb, &framesToRead, &pReadBuffer);
-            {
-                memcpy(pRunningOutput, pReadBuffer, framesToRead * ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels));
-            }
-            ma_pcm_rb_commit_read(&g_rb, framesToRead);
-
-            pRunningOutput += framesToRead * ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
-            pcmFramesProcessed += framesToRead;
-        } else {
-            /*
-            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;
-
-            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. */
-                data_callback_fixed(pDevice, pWriteBuffer, NULL, framesToWrite);
-            }
-            ma_pcm_rb_commit_write(&g_rb, framesToWrite);
-        }
-    }
-
-    /* Unused in this example. */
-    (void)pInput;
-}
-
-int main(int argc, char** argv)
-{
-    ma_waveform_config waveformConfig;
-    ma_device_config deviceConfig;
-    ma_device 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);
-
-    ma_pcm_rb_init(DEVICE_FORMAT, DEVICE_CHANNELS, PCM_FRAME_CHUNK_SIZE, NULL, NULL, &g_rb);
-    
-    deviceConfig = ma_device_config_init(ma_device_type_playback);
-    deviceConfig.playback.format   = DEVICE_FORMAT;
-    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. */
-
-    if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
-        printf("Failed to open playback device.\n");
-        ma_pcm_rb_uninit(&g_rb);
-        return -4;
-    }
-
-    printf("Device Name: %s\n", device.playback.name);
-
-    if (ma_device_start(&device) != MA_SUCCESS) {
-        printf("Failed to start playback device.\n");
-        ma_pcm_rb_uninit(&g_rb);
-        ma_device_uninit(&device);
-        return -5;
-    }
-    
-    printf("Press Enter to quit...\n");
-    getchar();
-
-    ma_device_uninit(&device);
-    ma_pcm_rb_uninit(&g_rb);
-
-    (void)argc;
-    (void)argv;
-    return 0;
-}
-
-
- - - - - - -
- -
- Copyright © 2022 David Reid
- Developed by David Reid - mackron@gmail.com -
- - diff --git a/docs/examples/index.html b/docs/examples/index.html index e32dc71d..6ea24398 100644 --- a/docs/examples/index.html +++ b/docs/examples/index.html @@ -245,10 +245,10 @@ a.doc-navigation-l4 {
+without gaps.
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference
Custom BackendThis example show how a custom backend can be implemented.
Custom DecoderDemonstrates how to implement a custom decoder.
Custom Decoder EngineDemonstrates how to implement a custom decoder and use it with the high level API.
Data Source ChainingDemonstrates one way to chain together a number of data sources so they play back seamlessly -without gaps.
Duplex EffectDemonstrates how to apply an effect to a duplex stream using the node graph system.
Engine AdvancedThis example demonstrates some of the advanced features of the high level engine API.
Engine EffectsDemonstrates how to apply an effect to sounds using the high level engine API.
Engine Hello WorldThis example demonstrates how to initialize an audio engine and play a sound.
Engine SteamaudioDemonstrates integration of Steam Audio with miniaudio's engine API.
Fixed Size CallbackShows one way to implement a data callback that is called with a fixed frame count.
Node GraphThis example shows how to use the node graph system.
Resource ManagerDemonstrates how you can use the resource manager to manage loaded sounds.
Resource Manager AdvancedDemonstrates how you can use the resource manager to manage loaded sounds.
Simple CaptureDemonstrates how to capture data from a microphone using the low-level API.
Simple DuplexDemonstrates duplex mode which is where data is captured from a microphone and then output to a speaker device.
Simple EnumerationDemonstrates how to enumerate over devices.
Simple LoopbackDemonstrates how to implement loopback recording.
Simple LoopingShows one way to handle looping of a sound.
Simple MixingDemonstrates one way to load multiple files and play them all back at the same time.
Simple PlaybackDemonstrates how to load a sound file and play it back using the low-level API.
Simple Playback SineDemonstrates playback of a sine wave.
Duplex EffectDemonstrates how to apply an effect to a duplex stream using the node graph system.
Engine AdvancedThis example demonstrates some of the advanced features of the high level engine API.
Engine EffectsDemonstrates how to apply an effect to sounds using the high level engine API.
Engine Hello WorldThis example demonstrates how to initialize an audio engine and play a sound.
Engine SdlShows how to use the high level engine API with SDL.
Engine SteamaudioDemonstrates integration of Steam Audio with miniaudio's engine API.
Node GraphThis example shows how to use the node graph system.
Resource ManagerDemonstrates how you can use the resource manager to manage loaded sounds.
Resource Manager AdvancedDemonstrates how you can use the resource manager to manage loaded sounds.
Simple CaptureDemonstrates how to capture data from a microphone using the low-level API.
Simple DuplexDemonstrates duplex mode which is where data is captured from a microphone and then output to a speaker device.
Simple EnumerationDemonstrates how to enumerate over devices.
Simple LoopbackDemonstrates how to implement loopback recording.
Simple LoopingShows one way to handle looping of a sound.
Simple MixingDemonstrates one way to load multiple files and play them all back at the same time.
Simple PlaybackDemonstrates how to load a sound file and play it back using the low-level API.
Simple Playback SineDemonstrates playback of a sine wave.
diff --git a/docs/examples/node_graph.html b/docs/examples/node_graph.html index f3fae9d3..ccc4a9f8 100644 --- a/docs/examples/node_graph.html +++ b/docs/examples/node_graph.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Node Graph

This example shows how to use the node graph system.

diff --git a/docs/examples/resource_manager.html b/docs/examples/resource_manager.html index 9a309032..fa657b5e 100644 --- a/docs/examples/resource_manager.html +++ b/docs/examples/resource_manager.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Resource Manager

Demonstrates how you can use the resource manager to manage loaded sounds.

diff --git a/docs/examples/resource_manager_advanced.html b/docs/examples/resource_manager_advanced.html index c22001d9..3348662a 100644 --- a/docs/examples/resource_manager_advanced.html +++ b/docs/examples/resource_manager_advanced.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Resource Manager Advanced

Demonstrates how you can use the resource manager to manage loaded sounds.

diff --git a/docs/examples/simple_capture.html b/docs/examples/simple_capture.html index 1a11c7c8..0ca2d2b5 100644 --- a/docs/examples/simple_capture.html +++ b/docs/examples/simple_capture.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Simple Capture

Demonstrates how to capture data from a microphone using the low-level API.

diff --git a/docs/examples/simple_duplex.html b/docs/examples/simple_duplex.html index 9819d194..c80392d3 100644 --- a/docs/examples/simple_duplex.html +++ b/docs/examples/simple_duplex.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Simple Duplex

Demonstrates duplex mode which is where data is captured from a microphone and then output to a speaker device.

diff --git a/docs/examples/simple_enumeration.html b/docs/examples/simple_enumeration.html index cc3fe207..00fdefa1 100644 --- a/docs/examples/simple_enumeration.html +++ b/docs/examples/simple_enumeration.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Simple Enumeration

Demonstrates how to enumerate over devices.

diff --git a/docs/examples/simple_loopback.html b/docs/examples/simple_loopback.html index 8d397f82..8b352d1f 100644 --- a/docs/examples/simple_loopback.html +++ b/docs/examples/simple_loopback.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Simple Loopback

Demonstrates how to implement loopback recording.

diff --git a/docs/examples/simple_looping.html b/docs/examples/simple_looping.html index 52bc63bf..147caba7 100644 --- a/docs/examples/simple_looping.html +++ b/docs/examples/simple_looping.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Simple Looping

Shows one way to handle looping of a sound.

diff --git a/docs/examples/simple_mixing.html b/docs/examples/simple_mixing.html index 41448a6a..70c1603d 100644 --- a/docs/examples/simple_mixing.html +++ b/docs/examples/simple_mixing.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Simple Mixing

Demonstrates one way to load multiple files and play them all back at the same time.

diff --git a/docs/examples/simple_playback.html b/docs/examples/simple_playback.html index c35a04a7..690c5e06 100644 --- a/docs/examples/simple_playback.html +++ b/docs/examples/simple_playback.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Simple Playback

Demonstrates how to load a sound file and play it back using the low-level API.

diff --git a/docs/examples/simple_playback_sine.html b/docs/examples/simple_playback_sine.html index 0ba169d3..6e03cfe1 100644 --- a/docs/examples/simple_playback_sine.html +++ b/docs/examples/simple_playback_sine.html @@ -245,7 +245,7 @@ a.doc-navigation-l4 {
@@ -3599,6 +3597,34 @@ should set this for any nodes that perform resampling.

+ + + +
+Documentation HomeProgramming ManualExamplesCustom BackendCustom DecoderCustom Decoder EngineData Source ChainingDuplex EffectEngine AdvancedEngine EffectsEngine Hello WorldEngine SdlEngine SteamaudioNode GraphResource ManagerResource Manager AdvancedSimple CaptureSimple DuplexSimple EnumerationSimple LoopbackSimple LoopingSimple MixingSimple PlaybackSimple Playback SineAPI Reference

Simple Playback Sine

Demonstrates playback of a sine wave.

diff --git a/docs/manual/index.html b/docs/manual/index.html index 404c0bac..3219ce69 100644 --- a/docs/manual/index.html +++ b/docs/manual/index.html @@ -1455,12 +1455,10 @@ runtime linking via dlopen().

-MA_DEBUG_OUTPUT -

+MA_DEBUG_OUTPUT

-Enable processing of MA_LOG_LEVEL_DEBUG messages and printf() -output.

+Enable printf() output of debug logs (MA_LOG_LEVEL_DEBUG).

+MA_NODE_FLAG_SILENT_OUTPUT + +

+

+ + +

+

+ + +

+

+ +

+

+Used to tell miniaudio that a node produces only +silent output. This is useful for nodes where you +don't want the output to contribute to the final +mix. An example might be if you want split your +stream and have one branch be output to a file. +When using this flag, you should avoid writing to +the output buffer of the node's processing +callback because miniaudio will ignore it anyway.

+

If you need to make a copy of an audio stream for effect processing you can use a splitter node