123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- using UnityEngine;
- using System.Collections;
- using System.Runtime.InteropServices;
- //-----------------------------------------------------------------------------
- // Copyright 2012-2017 RenderHeads Ltd. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace RenderHeads.Media.AVProMovieCapture
- {
- /// <summary>
- /// Captures audio from an audio listener and adds it to a buffer
- /// The AVPro Movie Capture plugin pulls the data from this buffer and flushes it periodically
- /// </summary>
- [RequireComponent(typeof(AudioListener))]
- [AddComponentMenu("AVPro Movie Capture/Unity Audio Capture (requires AudioListener)", 500)]
- public class UnityAudioCapture : MonoBehaviour
- {
- [SerializeField]
- private bool _debugLogging = false;
- private const int BufferSize = 16;
- private float[] _buffer = new float[0];
- private float[] _readBuffer = new float[0];
- private int _bufferIndex;
- private GCHandle _bufferHandle;
- private int _numChannels;
- private int _overflowCount;
- private object _lockObject = new object();
- public float[] Buffer { get { return _readBuffer; } }
- public int BufferLength { get { return _bufferIndex; } }
- public int NumChannels { get { return _numChannels; } }
- public System.IntPtr BufferPtr { get { return _bufferHandle.AddrOfPinnedObject(); } }
- public int OverflowCount
- {
- get { return _overflowCount; }
- }
- void OnEnable()
- {
- int bufferLength = 0;
- int numBuffers = 0;
- AudioSettings.GetDSPBufferSize(out bufferLength, out numBuffers);
- #if UNITY_5_4_OR_NEWER || UNITY_5
- _numChannels = GetNumChannels(AudioSettings.driverCapabilities);
- //if (AudioSettings.speakerMode != AudioSpeakerMode.Raw &&
- if (AudioSettings.speakerMode < AudioSettings.driverCapabilities)
- {
- _numChannels = GetNumChannels(AudioSettings.speakerMode);
- }
- if (_debugLogging)
- {
- Debug.Log(string.Format("[UnityAudioCapture] SampleRate: {0}hz SpeakerMode: {1} BestDriverMode: {2} (DSP using {3} buffers of {4} bytes using {5} channels)", AudioSettings.outputSampleRate, AudioSettings.speakerMode.ToString(), AudioSettings.driverCapabilities.ToString(), numBuffers, bufferLength, _numChannels));
- }
- #else
- _numChannels = GetNumChannels(AudioSettings.driverCaps);
- if (AudioSettings.speakerMode != AudioSpeakerMode.Raw &&
- AudioSettings.speakerMode < AudioSettings.driverCaps)
- {
- _numChannels = GetNumChannels(AudioSettings.speakerMode);
- }
- if (_debugLogging)
- {
- Debug.Log(string.Format("[UnityAudioCapture] SampleRate: {0}hz SpeakerMode: {1} BestDriverMode: {2} (DSP using {3} buffers of {4} bytes using {5} channels)", AudioSettings.outputSampleRate, AudioSettings.speakerMode.ToString(), AudioSettings.driverCaps.ToString(), numBuffers, bufferLength, _numChannels));
- }
- #endif
- _buffer = new float[bufferLength * _numChannels * numBuffers * BufferSize];
- _readBuffer = new float[bufferLength * _numChannels * numBuffers * BufferSize];
- _bufferIndex = 0;
- _bufferHandle = GCHandle.Alloc(_readBuffer, GCHandleType.Pinned);
- _overflowCount = 0;
- }
- void OnDisable()
- {
- lock (_lockObject)
- {
- _bufferIndex = 0;
- if (_bufferHandle.IsAllocated)
- _bufferHandle.Free();
- _readBuffer = _buffer = null;
- }
- _numChannels = 0;
- }
- public System.IntPtr ReadData(out int length)
- {
- lock (_lockObject)
- {
- System.Array.Copy(_buffer, 0, _readBuffer, 0, _bufferIndex);
- length = _bufferIndex;
- _bufferIndex = 0;
- }
- return _bufferHandle.AddrOfPinnedObject();
- }
- public void FlushBuffer()
- {
- lock (_lockObject)
- {
- _bufferIndex = 0;
- _overflowCount = 0;
- }
- }
- void OnAudioFilterRead(float[] data, int channels)
- {
- if (_buffer != null)
- {
- // TODO: use double buffering
- lock (_lockObject)
- {
- int length = Mathf.Min(data.Length, _buffer.Length - _bufferIndex);
- //System.Array.Copy(data, 0, _buffer, _bufferIndex, length);
- for (int i = 0; i < length; i++)
- {
- _buffer[i + _bufferIndex] = data[i];
- }
- _bufferIndex += length;
- if (length < data.Length)
- {
- _overflowCount++;
- Debug.LogWarning("[AVProMovieCapture] Audio buffer overflow, may cause sync issues. Disable this component if not recording Unity audio.");
- }
- }
- }
- }
- static public int GetNumChannels(AudioSpeakerMode mode)
- {
- int result = 0;
- switch (mode)
- {
- //case AudioSpeakerMode.Raw:
- // break;
- case AudioSpeakerMode.Mono:
- result = 1;
- break;
- case AudioSpeakerMode.Stereo:
- result = 2;
- break;
- case AudioSpeakerMode.Quad:
- result = 4;
- break;
- case AudioSpeakerMode.Surround:
- result = 5;
- break;
- case AudioSpeakerMode.Mode5point1:
- result = 6;
- break;
- case AudioSpeakerMode.Mode7point1:
- result = 8;
- break;
- case AudioSpeakerMode.Prologic:
- result = 2;
- break;
- }
- return result;
- }
- }
- }
|