V
V
Vladimir Korotenko2020-04-19 20:54:45
Android
Vladimir Korotenko, 2020-04-19 20:54:45

How to identify a peak in an audio recording?

Threw the task of recognizing the sound. It is necessary to determine the pace of clapping in the mobile application, in the palm of your hand, on the thigh or stomping. All this in a rather noisy room. Now I'm figuring out how to do it.
In theory, you need to cut off sound peaks with a duration of 0.1 -0.3 seconds. Perhaps I am reinventing the wheel and there is such a library? Please advise if you know or share your thoughts.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vladimir Korotenko, 2020-04-22
@firedragon

That's about what happened. The volume of the sample is pushed to the top of the application, then the analysis proceeds according to the current data.

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

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question