/// <summary> /// Extracts the audio data from an AudioClip and sets it in a GATData object. /// Memory is allocated according to the specified GATDataAllocationMode. /// </summary> public static GATData ToGATData(this AudioClip clip, GATDataAllocationMode mode) { GATData data; float[] tempArray; tempArray = new float[clip.samples]; clip.GetData(tempArray, 0); #if UNITY_EDITOR if (Application.isPlaying == false) { mode = GATDataAllocationMode.Unmanaged; } #endif if (mode == GATDataAllocationMode.Managed) { data = GATManager.GetDataContainer(clip.samples); data.CopyFrom(tempArray, 0, 0, clip.samples); } else if (mode == GATDataAllocationMode.Fixed) { data = GATManager.GetFixedDataContainer(clip.samples, "ClipData: " + clip.name); data.CopyFrom(tempArray, 0, 0, clip.samples); } else { data = new GATData(tempArray); } return(data); }
/// <summary> /// The splitter will begin broadcasting it's /// sub streams immediately. /// </summary> public GATAudioThreadStreamSplitter(IGATAudioThreadStream stream, GATDataAllocationMode bufferAllocationMode) { int i; _sourceStreamChannels = stream.NbOfChannels; if (_sourceStreamChannels < 2) { Debug.LogWarning("source stream is mono: " + stream.StreamName); } IntPtr outputBufferPointer = IntPtr.Zero; _sharedBufferSize = stream.BufferSizePerChannel; if (bufferAllocationMode == GATDataAllocationMode.Unmanaged) { _sharedBufferArray = new float[_sharedBufferSize]; _sharedBuffer = new GATData(_sharedBufferArray); } else { if (bufferAllocationMode == GATDataAllocationMode.Fixed) { _sharedBuffer = GATManager.GetFixedDataContainer(_sharedBufferSize, "StreamSplitter buffer"); } else { _sharedBuffer = GATManager.GetDataContainer(_sharedBufferSize); } _sharedBufferArray = _sharedBuffer.ParentArray; outputBufferPointer = _sharedBuffer.GetPointer(); } _memOffset = _sharedBuffer.MemOffset; _streamProxies = new GATAudioThreadStreamProxy[_sourceStreamChannels]; for (i = 0; i < _sourceStreamChannels; i++) { _streamProxies[i] = new GATAudioThreadStreamProxy(_sharedBufferSize, 1, outputBufferPointer, _sharedBuffer.MemOffset, (stream.StreamName + " split " + i)); } stream.AddAudioThreadStreamClient(this); _sourceStream = stream; }
/// <summary> /// Allocates caches retrievable in the Caches property. /// </summary> public void AllocateCaches(double duration, bool managedData) { if (!_isInited) { Start(); } if (_streamToCache != null && Caches != null) { _streamToCache.ReleaseCache(); } cacheDuration = duration; _cacheNumFrames = ( int )(cacheDuration * GATInfo.OutputSampleRate); useManagedData = managedData; GATData[] caches = new GATData[_stream.NbOfChannels]; int i; for (i = 0; i < caches.Length; i++) { if (useManagedData) { if (_cacheNumFrames > GATManager.DefaultDataAllocator.LargestFreeChunkSize) { int j; for (j = 0; j < i; j++) { caches[i].Release(); } throw new GATException("Chunk is too large to be allocated in managed memory, consider using unmanaged setting"); } caches[i] = GATManager.GetDataContainer(_cacheNumFrames); } else { caches[i] = new GATData(new float[_cacheNumFrames]); } } _streamToCache.Loop = _loopedCaching; _streamToCache.Caches = caches; }
/// <summary> /// Performs the same operation as ToGATData, but splits interleaved channels in seperate GATData /// instances. /// </summary> public static GATData[] ExtractChannels(this AudioClip clip, GATDataAllocationMode mode) { GATData[] channelsData; float[] tempArray; int i; int length; tempArray = new float[clip.samples * clip.channels]; clip.GetData(tempArray, 0); channelsData = new GATData[clip.channels]; length = clip.samples; #if UNITY_EDITOR if (Application.isPlaying == false) { mode = GATDataAllocationMode.Unmanaged; } #endif for (i = 0; i < clip.channels; i++) { if (mode == GATDataAllocationMode.Managed) { channelsData[i] = GATManager.GetDataContainer(length); } else if (mode == GATDataAllocationMode.Fixed) { channelsData[i] = GATManager.GetFixedDataContainer(length, clip.name + " channel" + i + " data"); } else { channelsData[i] = new GATData(new float[length]); } channelsData[i].CopyFromInterlaced(tempArray, length, i, clip.channels); } return(channelsData); }
void UpdateContainer() { if (_audioData != null) { _audioData.Release(); } #if UNITY_EDITOR if (Application.isPlaying) { _audioData = GATManager.GetDataContainer(_cachedLength); } else { _audioData = new GATData(new float[_cachedLength]); } #else _audioData = GATManager.GetDataContainer(_cachedLength); #endif _audioData.Retain(); }
/// <summary> /// Blocking load of wav and ogg files. /// </summary> public GATData[] LoadSync(AGATAudioFile file, GATDataAllocationMode allocationMode) { GATData[] loadedChannels; int i; bool didFail = false; loadedChannels = new GATData[file.Channels]; for (i = 0; i < file.Channels; i++) { if (allocationMode == GATDataAllocationMode.Fixed) //GZComment: allocation fail leaks { try{ loadedChannels[i] = GATManager.GetFixedDataContainer(file.NumFrames, file.FileName); } catch (System.Exception ex) { didFail = true; #if UNITY_EDITOR Debug.LogException(ex); #endif } } else if (allocationMode == GATDataAllocationMode.Managed) //GZComment: allocation fail leaks { try { loadedChannels[i] = GATManager.GetDataContainer(file.NumFrames); } catch (System.Exception ex) { didFail = true; #if UNITY_EDITOR Debug.LogException(ex); #endif } } else { loadedChannels[i] = new GATData(new float[file.NumFrames]); } } if (didFail) { for (i = 0; i < loadedChannels.Length; i++) { if (loadedChannels[i] != null) { loadedChannels[i].Release(); } } return(null); } if (file.Channels == 1) { file.ReadNextChunk(loadedChannels[0].ParentArray, loadedChannels[0].MemOffset, file.NumFrames); return(loadedChannels); } int framesPerRead; int framesRead; int totalFramesRead = 0; framesPerRead = _buffer.Length / file.Channels; while (true) { framesRead = file.ReadNextChunk(_buffer, 0, framesPerRead); for (i = 0; i < file.Channels; i++) { loadedChannels[i].CopyFromInterlaced(_buffer, framesRead, totalFramesRead, i, file.Channels); } totalFramesRead += framesRead; if (framesRead < framesPerRead) { break; } } return(loadedChannels); }
public GATData[] LoadNext(BackgroundWorker worker, float[] deInterleaveBuffer) { GATData[] containers; int i; int channels; if (_paths.Count == 0) { Status = LoadOperationStatus.Done; return(null); } AGATAudioFile file; try { file = AGATAudioFile.OpenAudioFileAtPath(_paths.Dequeue()); } catch (System.Exception e) { #if UNITY_EDITOR Debug.LogException(e); #endif FailReason = LoadOperationFailReason.CannotOpenFile; Status = LoadOperationStatus.Failed; return(null); } using ( file ) { channels = file.Channels; CurrentFileName = file.FileName; if (!_forceMono && channels > 1) { containers = new GATData[channels]; } else { containers = new GATData[1]; } for (i = 0; i < containers.Length; i++) { if (_allocationMode == GATDataAllocationMode.Fixed) //GZComment: allocation fail leaks { try{ containers[i] = GATManager.GetFixedDataContainer(file.NumFrames, file.FileName); } catch (System.Exception ex) { ReleaseContainers(containers); Status = LoadOperationStatus.Failed; FailReason = LoadOperationFailReason.OutOfPreAllocatedMemory; #if UNITY_EDITOR Debug.LogException(ex); #endif return(null); } } else if (_allocationMode == GATDataAllocationMode.Managed) //GZComment: allocation fail leaks { try { containers[i] = GATManager.GetDataContainer(file.NumFrames); } catch (System.Exception ex) { ReleaseContainers(containers); Status = LoadOperationStatus.Failed; FailReason = LoadOperationFailReason.NoLargeEnoughChunkInAllocator; #if UNITY_EDITOR Debug.LogException(ex); #endif return(null); } } else { containers[i] = new GATData(new float[file.NumFrames]); } } int framesPerRead; int framesRead; int totalFramesRead = 0; if (channels > 1) { framesPerRead = deInterleaveBuffer.Length / channels; while (true) { if (worker.CancellationPending) { ReleaseContainers(containers); return(null); } framesRead = file.ReadNextChunk(deInterleaveBuffer, 0, framesPerRead); if (_forceMono) // Only supported for stereo files { int numSamples = framesRead * channels; for (i = 0; i < numSamples; i += channels) { deInterleaveBuffer[i] += deInterleaveBuffer[i + 1]; } containers[0].CopyFromInterlaced(deInterleaveBuffer, framesRead, totalFramesRead, 0, channels); } else { for (i = 0; i < channels; i++) { containers[i].CopyFromInterlaced(deInterleaveBuffer, framesRead, totalFramesRead, i, channels); } } totalFramesRead += framesRead; if (_reportsProgress) { worker.ReportProgress(0, new ProgressInfo(( float )totalFramesRead / file.NumFrames, file.FileName)); } if (framesRead < framesPerRead) { break; } } } else { int framesLeft; while (totalFramesRead < file.NumFrames) { if (worker.CancellationPending) { ReleaseContainers(containers); return(null); } framesLeft = file.NumFrames - totalFramesRead; framesPerRead = (framesLeft < 16384 ? framesLeft : 16384); framesRead = file.ReadNextChunk(containers[0].ParentArray, containers[0].MemOffset + totalFramesRead, framesPerRead); totalFramesRead += framesRead; if (_reportsProgress) { worker.ReportProgress(0, new ProgressInfo(( float )totalFramesRead / file.NumFrames, file.FileName)); } } } } return(containers); }