C# 如何从流中实时分析或读取数据-Windows universal 10

C# 如何从流中实时分析或读取数据-Windows universal 10,c#,windows-phone,windows-10,windows-10-universal,windows-10-mobile,C#,Windows Phone,Windows 10,Windows 10 Universal,Windows 10 Mobile,我在MemoryRandomAccessStream中有,我在那里捕获音频数据,() 可以实时分析流吗?我想设置阈值并读取高于阈值的数据,等等。所以,它就是这样一个检测器,它可以检测声音的特定振幅。例如,它可以计算峰值或其他 我也会对实现感到满意,在这个实现中,我只需在指定的时间段内检查来自jack plug的输入。然后我也会得到数据点 ================================================================================

我在MemoryRandomAccessStream中有
,我在那里捕获音频数据,()

可以实时分析流吗?我想设置阈值并读取高于阈值的数据,等等。所以,它就是这样一个检测器,它可以检测声音的特定振幅。例如,它可以计算峰值或其他

我也会对实现感到满意,在这个实现中,我只需在指定的时间段内检查来自jack plug的输入。然后我也会得到数据点

===================================================================================================================

编辑:现在我有了解决方案。 记录器的基本实现如下。我刚刚将设备id更改为正确的

            MediaCaptureInitializationSettings settings = new MediaCaptureInitializationSettings
            {
                StreamingCaptureMode = StreamingCaptureMode.Audio
            };
            settings.AudioProcessing = Windows.Media.AudioProcessing.Raw;
            settings.AudioDeviceId = myDeviceId;
音频设置:

       profile = MediaEncodingProfile.CreateWav(AudioEncodingQuality.Auto);
       profile.Audio.SampleRate = (uint) samplesPerSecond; // Samples per second
       profile.Audio.BitsPerSample = (uint) bitsPerSample; // bits per sample
       profile.Audio.ChannelCount = (uint) channels; // channels
       // Capture to stream 
       await capture.StartRecordToStreamAsync(profile, buffer);
正在运行录制时读取的任务

        // Copy the capturing stream
        readingStream = buffer.CloneStream().AsStreamForRead();

        // Set delay for fetching data
        double period = 1 /((double) samplesPerSecond);
        int delay = (int) Math.Ceiling(period * 1000); // Convert to milliseconds

        // Set size for byte array
        int bitsPerSecond = samplesPerSecond * bitsPerSample;
        int bitsPerPeriod = (int) Math.Floor(period * bitsPerSecond);
        int bytesPerPeriod = (int) bitsPerPeriod / 2;
        byte[] bytes = new byte[bytesPerPeriod];

        // Seems to work better this way
        delay = 2 * delay;

        while (readingStream.CanRead)
        {
            if (!Recording)
            {
                break;
            }

            // Reading frequency
            await Task.Delay(delay);
            // Read available bytes
            await readingStream.ReadAsync(bytes, 0, bytes.Length);
            // Get Avarage value of decoded bytes
            amplitude = Math.Abs(Decode(bytes).Average());

            // Update UI (These are my own methods to convert data to more human friendly format)
            GeneralUtil.setAmplitudeBarValue(amplitude);
            if (amplitude>treshold)
            {
                GeneralUtil.visualizePulse();
            }
        }

延迟时间和读取并不完全适合atm,但它只需要对变量进行少量调整。

您的解决方案不太好:随着时间的推移,会烧坏电池,消耗RAM,并带来额外的延迟

相反,您应该为StartRecordToStreamAsync调用提供自己的IRandomaccesstream接口实现。这样,您就不需要无休止的循环,也不需要等待调用

每次操作系统为您提供一部分音频数据时,都会调用WriteAsync方法。你可以用这些数据做任何你想做的事情

如果您不保存记录,只进行实时分析,那么您甚至不需要底层流对象。只需分析音频部分(但别忘了跳过wav标题),不要将其写入任何地方,然后放手


如果需要保存录音,请将其保存到文件中,不要将音频数据保存在RAM中。

您的解决方案不太好:会烧坏电池,随着时间的推移会消耗RAM,并带来额外的延迟

相反,您应该为StartRecordToStreamAsync调用提供自己的IRandomaccesstream接口实现。这样,您就不需要无休止的循环,也不需要等待调用

每次操作系统为您提供一部分音频数据时,都会调用WriteAsync方法。你可以用这些数据做任何你想做的事情

如果您不保存记录,只进行实时分析,那么您甚至不需要底层流对象。只需分析音频部分(但别忘了跳过wav标题),不要将其写入任何地方,然后放手

如果需要保存录音,请将其保存到文件中,不要将音频数据保存在RAM中

        // Copy the capturing stream
        readingStream = buffer.CloneStream().AsStreamForRead();

        // Set delay for fetching data
        double period = 1 /((double) samplesPerSecond);
        int delay = (int) Math.Ceiling(period * 1000); // Convert to milliseconds

        // Set size for byte array
        int bitsPerSecond = samplesPerSecond * bitsPerSample;
        int bitsPerPeriod = (int) Math.Floor(period * bitsPerSecond);
        int bytesPerPeriod = (int) bitsPerPeriod / 2;
        byte[] bytes = new byte[bytesPerPeriod];

        // Seems to work better this way
        delay = 2 * delay;

        while (readingStream.CanRead)
        {
            if (!Recording)
            {
                break;
            }

            // Reading frequency
            await Task.Delay(delay);
            // Read available bytes
            await readingStream.ReadAsync(bytes, 0, bytes.Length);
            // Get Avarage value of decoded bytes
            amplitude = Math.Abs(Decode(bytes).Average());

            // Update UI (These are my own methods to convert data to more human friendly format)
            GeneralUtil.setAmplitudeBarValue(amplitude);
            if (amplitude>treshold)
            {
                GeneralUtil.visualizePulse();
            }
        }