Как анализировать или читать данные в реальном времени с stream- Windows universal 10

58
6

У меня есть InMemoryRandomAccessStream stream, где я записываю аудиоданные, (реализацию)

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

Можно ли анализировать поток в реальном времени? Я хочу установить данные и прочитать данные выше порога и т.д. Итак, это такой детектор, который обнаруживает указанные амплитуды звуков. Например, он может считать вершины или что-то еще.

Я тоже был бы доволен реализацией, когда я просто проверю входные данные от штепсельной вилки в указанные периоды времени. Тогда я тоже получу данные.

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

Изменить: теперь у меня есть решение для этого. Базовая реализация рекордера соответствует этой Windows 10 Universal Windows Platform - Audio Recorder. Я только что изменил идентификатор устройства, чтобы исправить его.

            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();
}
}

Время задержки и чтение не подходят идеально, но для переменных требуется лишь небольшая корректировка.

спросил(а) 2020-04-04T00:22:17+03:00 6 месяцев, 3 недели назад
1
Решение
114

Ваше решение не подходит: сжигает батарею, ест оперативную память со временем и приносит дополнительную задержку.

Вместо этого вы должны предоставить свою собственную реализацию интерфейса IRandomAccessStream для вызова StartRecordToStreamAsync. Таким образом, вам не нужны бесконечные циклы и нет ожидающих вызовов.

Это точка отсчета.

Метод WriteAsync будет вызываться каждый раз, когда ОС имеет часть аудиоданных для вас. Вы можете делать все, что хотите, с данными.

Если вы не сохраняете запись только для этого анализа в реальном времени, вам даже не нужен базовый объект Stream. Просто проанализируйте часть звука (не забудьте пропустить wav-заголовок, однако), не пишите нигде и не отпускайте.

Если вам нужно сохранить запись, сохраните ее в файле, не храните аудиоданные в ОЗУ.

ответил(а) 2020-04-04T00:38:25.745298+03:00 6 месяцев, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема