AudioSampleProvider
класс в UnityEngine.Experimental.Audio
Выполнено в:UnityEngine.AudioModule
Описание
Обеспечивает доступ к звуковым семплам, генерируемым объектами Unity, такими как VideoPlayer.
Этот класс рассчитан на использование вне главного потока, а реализация исходит из того, что в каждый момент вызывающий её потребитель только один AudioSampleProvider.ConsumeSampleFrames. Аудиоданные могут быть доступны как из C#, так и из C++, в зависимости от того, что нужно сделать с этими данными.
Ниже приведен пример того, как получить доступ к образцам из C# с помощью аксессора, полученного из VideoPlayer:
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... } } }
Ниже приводится пример того, как получить доступ к образцам из C++. Настройка должна быть сделана в C# а затем UnityЯдро и нативный плагин могут вызывать друг друга без необходимости проходить через управляемый код.
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); }
И вот сопутствующий C++ плагин:
#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... }
Статические свойства
| Свойство | Описание |
|---|---|
| consumeSampleFramesNativeFunction | Указатель на собственную функцию, обеспечивающую доступ к кадрам звуковых образцов. |
Свойства
| Свойство | Описание |
|---|---|
| availableSampleFrameCount | Число кадров образца, доступных для потребления с AudioSampleProvider.ConsumeSampleFrames. |
| channelCount | Число аудиоканалов в кадре образца. |
| enableSampleFramesAvailableEvents | Включает события AudioSampleProvider.sampleFramesAvailable. |
| enableSilencePadding | Если true, то буферы, созданные ConsumeSampleFrames, будут заполнены в момент молчания, если их будет меньше, чем требуется. В противном случае, дополнительные кадры в буфере останутся неизменными. |
| freeSampleFrameCount | Число кадров образца, в которые все еще может быть сделана запись производителем образца до переполнения. |
| freeSampleFrameCountLowThreshold | Когда число свободных выборок падает ниже этого порога, происходит событие AudioSampleProvider.sampleFramesAvailable и связанное с ним основное событие. |
| id | Уникальный идентификатор для этого экземпляра. |
| maxSampleFrameCount | Максимальное количество кадров сэмплов, которое может накопиться во внутреннем буфере до появления события переполнения. |
| owner | Объект, из которого поступил этот поставщик. |
| sampleRate | Ожидаемая частота воспроизведения кадров сэмплов, формируемых этим классом. |
| trackIndex | Индекс трека в объекте, который создал этот поставщик. |
| valid | True, если объект допустим. |
Открытые методы
| Метод | Описание |
|---|---|
| ClearSampleFramesAvailableNativeHandler | Очистить набор обработчиков с помощью AudioSampleProvider.SetSampleFramesAvailableNativeHandler. |
| ClearSampleFramesOverflowNativeHandler | Очистить набор обработчиков с помощью AudioSampleProvider.SetSampleFramesOverflowNativeHandler. |
| ConsumeSampleFrames | Забирает кадры сэмплов из внутреннего буфера. |
| Dispose | Освобождает внутренние ресурсы. Унаследовано от IDisposable. |
| SetSampleFramesAvailableNativeHandler | Задайте основной обработчик событий для событий, которые возникают, когда количество доступных кадров выборки превышает порог. |
| SetSampleFramesOverflowNativeHandler | Задаёт нативный обработчик событий, возникающих при переполнении внутреннего буфера кадров сэмплов. |
Мероприятия
| Мероприятие | Описание |
|---|---|
| sampleFramesAvailable | Вызывается, когда количество доступных кадров выборки превышает порог, установленный AudioSampleProvider.freeSampleFrameCountLowThreshold. |
| sampleFramesOverflow | Вызывается, когда количество доступных кадров сэмплов превышает максимум, помещающийся во внутренний буфер. |
Делегаты
| делегат | Описание |
|---|---|
| ConsumeSampleFramesNativeFunction | Тип, который представляет собой указатель основной функции для потребления кадров образца. |
| SampleFramesEventNativeFunction | Тип, который представляет собой указатель основной функции для обработки событий образца кадра. |
| SampleFramesHandler | Делегирование для примерных событий кадра. |