如何从流 - Windows通用10实时分析或读取数据

时间:2016-03-17 19:01:52

标签: c# windows-phone windows-10 windows-10-universal windows-10-mobile

我有InMemoryRandomAccessStream stream,我在那里捕捉音频数据,(implemention

await capture.StartRecordToStreamAsync(MediaEncodingProfile.CreateMp3(AudioEncodingQuality.Auto), stream);" .

是否可以实时分析流?我想设置thershold并读取高于阈值的数据等。因此,它是一个检测声音指定幅度的探测器。例如,它可以计算峰值或其他值。

我也很高兴实施,我只是在指定的时间周期内检查插头的输入。然后我也会得到数据点。

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

编辑:现在我有了解决方法。 记录器的基本实现遵循Windows 10 Universal Windows Platform – Audio Recorder。我刚刚更改了设备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();
            }
        }

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

1 个答案:

答案 0 :(得分:0)

你的解决方案并不好:燃烧电池,随着时间的推移吃掉RAM,并带来额外的延迟。

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

Here’s some starting point.

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

如果您不保存仅执行该实时分析的录制内容,则甚至不需要基础Stream对象。只需分析一下音频部分(不要忘记跳过wav标题),不要把它写在任何地方,然后放手。

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