# AudioSampleProvider

> Provides access to the audio samples generated by Unity objects such as VideoPlayer.

## Definition

* **Type:** Class
* **Namespace:** [UnityEngine.Experimental.Audio](/engine/6000.7/script-reference/unityengine/experimental/audio.md)
* **Assembly:** UnityEngine.AudioModule
* **Implements:** [IDisposable](https://learn.microsoft.com/dotnet/api/system.idisposable)

```csharp
public class AudioSampleProvider : IDisposable
```

## Remarks

This class is meant to be usable outside the main thread and the implementation assumes a single consumer at a time invoking [AudioSampleProvider.ConsumeSampleFrames](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/consumesampleframes.md). Audio data can be accessed both from C# and from C++, depending on what has to be done with this data.

The following is an example of how to access samples from C# using an accessor obtained from the [VideoPlayer](/engine/6000.7/script-reference/unityengine/video/videoplayer.md):

The following is an example of how to access samples from C++. The setup has to be done in C# and then Unity's core and the native plug-in can call into each other without having to go through managed code.

And here is the accompanying C++ plug-in:

## Examples

```csharp
using UnityEngine;
using Unity.Collections;
using UnityEngine.Experimental.Video;
using UnityEngine.Experimental.Audio;
using UnityEngine.Video;

public class ManagedAudioOutput : MonoBehaviour
{
    AudioSampleProvider provider;

    void Start()
    {
        VideoPlayer vp = GetComponent<VideoPlayer>();
        vp.audioOutputMode = VideoAudioOutputMode.APIOnly;
        vp.prepareCompleted += Prepared;
        vp.Prepare();
    }

    void Prepared(VideoPlayer vp)
    {
        provider = vp.GetAudioSampleProvider(0);
        provider.sampleFramesAvailable += SampleFramesAvailable;
        provider.enableSampleFramesAvailableEvents = true;
        provider.freeSampleFrameCountLowThreshold = provider.maxSampleFrameCount / 4;
        vp.Play();
    }

    void SampleFramesAvailable(AudioSampleProvider provider, uint sampleFrameCount)
    {
        using (NativeArray<float> buffer = new NativeArray<float>(
                       (int)sampleFrameCount * provider.channelCount, Allocator.Temp))
        {
            var sfCount = provider.ConsumeSampleFrames(buffer);
            Debug.LogFormat("SetupSoftwareAudioOut.Available got {0} sample frames.", sfCount);
            // Do something with the samples here...
        }
    }
}
```

```csharp
using System;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Experimental.Video;
using UnityEngine.Experimental.Audio;
using UnityEngine.Video;

public class NativeAudioOutput : MonoBehaviour
{
    AudioSampleProvider provider;
    AudioSampleProvider.SampleFramesEventNativeFunction sampleFramesAvailableNativeHandler =
        SampleFramesAvailable;

    void Start()
    {
        VideoPlayer vp = GetComponent<VideoPlayer>();
        vp.audioOutputMode = VideoAudioOutputMode.APIOnly;
        vp.prepareCompleted += Prepared;
        vp.Prepare();
    }

    void Prepared(VideoPlayer vp)
    {
        provider = vp.GetAudioSampleProvider(0);
        provider.freeSampleFrameCountLowThreshold = provider.maxSampleFrameCount - 1024;

        SetConsumeSampleFramesFunction(
            AudioSampleProvider.consumeSampleFramesNativeFunction, provider.id,
            provider.channelCount, provider.sampleRate);
        provider.SetSampleFramesAvailableNativeHandler(
            sampleFramesAvailableNativeHandler, (IntPtr)0);

        vp.Play();
    }

    private const string pluginName =
#if UNITY_IPHONE
        "__Internal"
#else
        "NativeAudioOutputPlugin"
#endif
    ;

    [DllImport(pluginName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
    private static extern void SetConsumeSampleFramesFunction(
        AudioSampleProvider.ConsumeSampleFramesNativeFunction cb, uint id, ushort channelCount, uint sampleRate);

    [AOT.MonoPInvokeCallback(typeof(AudioSampleProvider.SampleFramesEventNativeFunction))]
    [DllImport(pluginName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
    private static extern void SampleFramesAvailable(IntPtr userData, uint id, uint sampleFrameCount);
}
```

```csharp
#include <algorithm>
#include <stdint.h>

typedef uint32_t(__cdecl *ConsumeSampleFramesFunction)(
    uint32_t providerId, float* interleavedSampleFrames, uint32_t sampleFrameCount);

ConsumeSampleFramesFunction ConsumeSampleFrames = NULL;
uint32_t providerId = -1;
float* buffer = NULL;
uint32_t bufferSampleFrameCount = 0;
uint32_t availableSampleFrameCount = 0;

extern "C" __cdecl void SetConsumeSampleFramesFunction(
    ConsumeSampleFramesFunction function, uint32_t id, uint16_t channelCount, uint32_t sampleRate)
{
    ConsumeSampleFrames = function;
    providerId = id;
    delete[] buffer;
    buffer = new float[channelCount * sampleRate]; // 1s worth of sample frames.
    bufferSampleFrameCount = sampleRate;
}

extern "C" __cdecl void SampleFramesAvailable(void* userData, uint32_t id, uint32_t sampleFrameCount)
{
    if (ConsumeSampleFrames == NULL)
        return;

    // We consume the sample frames from the handler that tells us that there are some available.
    // But we could also invoke this regularly from another thread, for example the thread providing
    // samples to an audio device.
    const uint32_t consumedSampleFrameCount = ConsumeSampleFrames(
            providerId, buffer, std::min(bufferSampleFrameCount, sampleFrameCount));
    // Do something with the samples here...
}
```

## Properties

| Property                                                                                                                                                     | Description                                                                                                                                                                                                                               |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [availableSampleFrameCount](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/availablesampleframecount.md)                 | Number of sample frames available for consuming with [AudioSampleProvider.ConsumeSampleFrames](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/consumesampleframes.md).                                |
| [channelCount](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/channelcount.md)                                           | The number of audio channels per sample frame.                                                                                                                                                                                            |
| [enableSampleFramesAvailableEvents](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/enablesampleframesavailableevents.md) | Enables the [\_sampleFramesAvailable](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/sampleframesavailable.md) events.                                                                                |
| [enableSilencePadding](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/enablesilencepadding.md)                           | If true, buffers produced by ConsumeSampleFrames will get padded when silence if there are less available than asked for. Otherwise, the extra sample frames in the buffer will be left unchanged.                                        |
| [freeSampleFrameCount](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/freesampleframecount.md)                           | Number of sample frames that can still be written to by the sample producer before overflowing.                                                                                                                                           |
| [freeSampleFrameCountLowThreshold](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/freesampleframecountlowthreshold.md)   | When the free sample count falls below this threshold, the [\_sampleFramesAvailable](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/sampleframesavailable.md) event and associated native is emitted. |
| [id](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/id.md)                                                               | Unique identifier for this instance.                                                                                                                                                                                                      |
| [maxSampleFrameCount](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/maxsampleframecount.md)                             | The maximum number of sample frames that can be accumulated inside the internal buffer before an overflow event is emitted.                                                                                                               |
| [owner](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/owner.md)                                                         | Object where this provider came from.                                                                                                                                                                                                     |
| [sampleRate](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/samplerate.md)                                               | The expected playback rate for the sample frames produced by this class.                                                                                                                                                                  |
| [trackIndex](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/trackindex.md)                                               | Index of the track in the object that created this provider.                                                                                                                                                                              |
| [valid](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/valid.md)                                                         | True if the object is valid.                                                                                                                                                                                                              |

## Static Properties

| Property                                                                                                                                                       | Description                                                                 |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| [consumeSampleFramesNativeFunction](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/consumesampleframesnativefunction-1.md) | Pointer to the native function that provides access to audio sample frames. |

## Methods

| Method                                                                                                                                                                   | Description                                                                                                                                                                                                                 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [ClearSampleFramesAvailableNativeHandler](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/clearsampleframesavailablenativehandler.md) | Clear the native handler set with [AudioSampleProvider.SetSampleFramesAvailableNativeHandler](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/setsampleframesavailablenativehandler.md). |
| [ClearSampleFramesOverflowNativeHandler](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/clearsampleframesoverflownativehandler.md)   | Clear the native handler set with [AudioSampleProvider.SetSampleFramesOverflowNativeHandler](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/setsampleframesoverflownativehandler.md).   |
| [ConsumeSampleFrames](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/consumesampleframes.md)                                         | Consume sample frames from the internal buffer.                                                                                                                                                                             |
| [Dispose](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/dispose.md)                                                                 | Release internal resources. Inherited from IDisposable.                                                                                                                                                                     |
| [SetSampleFramesAvailableNativeHandler](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/setsampleframesavailablenativehandler.md)     | Set the native event handler for events emitted when the number of available sample frames crosses the threshold.                                                                                                           |
| [SetSampleFramesOverflowNativeHandler](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/setsampleframesoverflownativehandler.md)       | Set the native event handler for events emitted when the internal sample frame buffer overflows.                                                                                                                            |

## Events

| Member                                                                                                                               | Description                                                                                                                                                                                                                                         |
| ------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [sampleFramesAvailable](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/sampleframesavailable.md) | Invoked when the number of available sample frames goes beyond the threshold set with [\_freeSampleFrameCountLowThreshold](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/freesampleframecountlowthreshold.md). |
| [sampleFramesOverflow](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/sampleframesoverflow.md)   | Invoked when the number of available sample frames goes beyond the maximum that fits in the internal buffer.                                                                                                                                        |

## Delegates

| Delegate                                                                                                                                                                         | Description                                                                        |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| [AudioSampleProvider.ConsumeSampleFramesNativeFunction](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/consumesampleframesnativefunction.md) | Type that represents the native function pointer for consuming sample frames.      |
| [AudioSampleProvider.SampleFramesEventNativeFunction](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/sampleframeseventnativefunction.md)     | Type that represents the native function pointer for handling sample frame events. |
| [AudioSampleProvider.SampleFramesHandler](/engine/6000.7/script-reference/unityengine/experimental/audio/audiosampleprovider/sampleframeshandler.md)                             | Delegate for sample frame events.                                                  |
