我编写了一个方法来获取表示音乐文件样本的float数组。我正在使用AudioGraph类。
但是当我处理AudioGraph时,我收到以下错误:
调用Dispose但在返回Method之后(下次我等待之后),不会发生错误。
代码不在UI线程上运行。在UI线程上运行不会抛出此错误。
不处理图表是另一种不抛出此错误的方法。我不喜欢这两个。
这是方法:
private static async Task<float[]> GetAudioBuffer(IStorageFile file, IProgress<double> progress)
{
float[] buffer;
int currentPart = 0;
progress.Report(currentPart, 0);
var createAudioGraphResult = await Windows.Media.Audio.AudioGraph.CreateAsync(new Windows.Media.Audio.AudioGraphSettings(Windows.Media.Render.AudioRenderCategory.Media));
if (createAudioGraphResult.Status != AudioGraphCreationStatus.Success)
CallError();
using (var graph = createAudioGraphResult.Graph)
{
var result = await graph.CreateFileInputNodeAsync(file);
if (result.Status != AudioFileNodeCreationStatus.Success)
CallError();
var input = result.FileInputNode;
{
var output = graph.CreateFrameOutputNode();
{
input.AddOutgoingConnection(output);
TaskCompletionSource<bool> waiter = new TaskCompletionSource<bool>();
input.FileCompleted += (node, args) =>
{
if (!waiter.TrySetResult(true))
System.Diagnostics.Debug.WriteLine("This should be called only once");
};
graph.Start();
Task t = waiter.Task;
Task erg = null;
while (erg != t)
{
var delay = Task.Delay(500);
erg = await Task.WhenAny(t, delay);
var percentage = input.Position.TotalSeconds / input.Duration.TotalSeconds;
progress.Report(currentPart, percentage);
}
await waiter.Task;
progress.Report(currentPart, 1);
currentPart++;
graph.Stop();
using (var frame = output.GetFrame())
using (var lockedBuffer = frame.LockBuffer(Windows.Media.AudioBufferAccessMode.Read))
using (var refference = lockedBuffer.CreateReference())
unsafe
{
var memoryByteAccess = refference as IMemoryBufferByteAccess;
byte* p;
uint capacity;
memoryByteAccess.GetBuffer(out p, out capacity);
int length = (int)(capacity / sizeof(float));
float* b = (float*)p;
var channelCount = output.EncodingProperties.ChannelCount;
buffer = new float[length / channelCount];
for (int i = 0; i < length / channelCount; i++)
{
for (int j = 0; j < channelCount; j++)
buffer[i] += b[i * channelCount + j];
buffer[i] /= channelCount;
var percentage = i / (double)(length / channelCount);
progress.Report(currentPart, percentage);
}
currentPart++;
}
}
}
}
return buffer;
}