firedragon
@firedragon
Не джун-мидл-сеньор, а трус-балбес-бывалый.

Как определить пик на аудио записи?

Подкинули задачу по распознаванию звука. Нужно в мобильном приложении определять темп хлопков, в ладоши, по бедру или притопывания. Все это в довольно шумном помещении. Сейчас придумываю как это осуществить.
По идее нужно отсекать пики звука с длительностью 0,1 -0,3 сек. Возможно я изобретаю велосипед и есть такая библиотека? Посоветуйте если знаете или поделитесь соображениями.
  • Вопрос задан
  • 74 просмотра
Решения вопроса 1
firedragon
@firedragon Автор вопроса
Не джун-мидл-сеньор, а трус-балбес-бывалый.
То что примерно получилось. Громкость сэмпла прокидывается вверх приложения, дальше анализ идет по текущим данным.

using Android.Media;
using Android.Util;
using PeakMeter.Code;
using System;
using System.Threading;

[assembly: Xamarin.Forms.Dependency(typeof(AudioRecorder))]
// ReSharper disable once CheckNamespace
namespace PeakMeter.Code
{
    public class AudioRecorder : IAudioRecorder
    {
        private AudioRecord _audioRecord;
        public const string TAG = "PeakMeter";
        private float _maxPeak = 0f;
        private bool _shouldContinue;
        public void Start()
        {
            _shouldContinue = true;
            var thread = new Thread(new ThreadStart(ThreadWorker));
            thread.Start();
        }

        private void ThreadWorker()
        {
            const int sampleRate = 44100;
            const ChannelIn channelConfig = ChannelIn.Mono;
            const Encoding audioFormat = Encoding.Pcm16bit;

            var bufferSize = AudioRecord.GetMinBufferSize(sampleRate,
                channelConfig,
                audioFormat);


            if (bufferSize == (int)TrackStatus.Error || bufferSize == (int)TrackStatus.ErrorBadValue)
            {
                bufferSize = sampleRate * 2;
            }

            Log.Debug(TAG, $"bufferSize = {bufferSize}");

            var audioBuffer = new short[bufferSize / 2];


            _audioRecord = new AudioRecord(AudioSource.Default,
                sampleRate,
                channelConfig,
                audioFormat,
                bufferSize);

            if (_audioRecord.State != State.Initialized)
            {
                Log.Error(TAG, "Audio Record can't initialize!");
                return;
            }
            _audioRecord.StartRecording();
            Log.Verbose(TAG, "Start recording");
            long shortsRead = 0;
            while (_shouldContinue)
            {
                var numberOfShort = _audioRecord.Read(audioBuffer, 0, audioBuffer.Length);
                shortsRead += numberOfShort;
                foreach (var s in audioBuffer)
                {
                    if (s > _maxPeak)
                        NewPeak?.Invoke(this, (float)s);
                    _maxPeak = Math.Max(_maxPeak, s);
                }

                PeakLevel?.Invoke(this, _maxPeak);
            }

            _audioRecord.Stop();
            _audioRecord.Release();
            _audioRecord = null;

            Log.Verbose(TAG, $"Recording stopped. Samples read: {shortsRead}");
        }

        public void Stop()
        {
            _shouldContinue = false;
        }
        public event EventHandler<float> PeakLevel;
        public event EventHandler<float> NewPeak;
    }
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы