Record, change and play sound on iOS

EDIT: In the end, I used what I explained below, AVRecorder for recording speech and openAL for shifting and reproducing the pitch. It worked out quite well.

I have a question about recording, changing and playing sound. Earlier, I asked a similar question ( Recording, pitch change and real-time audio playback in iOS ), but now I have additional information and you can do some further tips.

So, firstly, this is what I am trying to do (in a separate thread in the main thread):

  • iphone microphone monitor
  • check sound exceeding a certain volume
  • if above the threshold for recording, for example. the person begins to speak
  • continue recording until the volume falls below a threshold, for example. the man stops.
  • change the pitch of the recorded sound.
  • reproduced sound

I was thinking about using AVRecorder to monitor and record sound, a good tutorial here: http://mobileorchard.com/tutorial-detecting-when-a-user-blows-into-the-mic/

and I was thinking about using openAL to change the height of the recorded sound.

So my question is that my thinking is correct in the above list of points, am I missing something or is there a better / easier way to do this. Can I not mix audio libraries and just use AVFoundation to change the pitch?

0
2

AVRecorder - , - IO .

"" . , RMS , RMS (, 300 , VU).

. dBFS 10 * log10f (sqrt (sum/num_samples)), sqrt 20 * log10f (sum/num_samples).

, , .

, OpenAL , , , - https://ccrma.stanford.edu/~jos/resample/Theory_Ideal_Bandlimited_Interpolation.html

. . , ;)

:

class VUMeter
{

protected:

    // samples per second
    float _sampleRate;

    // the integration time in seconds (vu meter is 300ms)
    float _integrationTime;

    // these maintain a circular buffer which contains
    // the 'squares' of the audio samples

    int _integrationBufferLength;
    float *_integrationBuffer;
    float *_integrationBufferEnd;
    float *_cursor;

    // this is a sort of accumulator to make a running
    // average more efficient

    float _sum;

public:

    VUMeter()
    : _sampleRate(48000.0f)
    , _integrationTime(0.3f)
    , _sum(0.)
    {
        // create a buffer of values to be integrated
        // e.g 300ms @ 48khz is 14400 samples

        _integrationBufferLength = (int) (_integrationTime * _sampleRate);

        _integrationBuffer = new float[_integrationBufferLength + 1];
        bzero(_integrationBuffer, _integrationBufferLength);

        // set the pointers for our ciruclar buffer

        _integrationBufferEnd = _integrationBuffer + _integrationBufferLength;
        _cursor = _integrationBuffer;

    }

    ~VUMeter()
    {
        delete _integrationBuffer;
    }

    float getRms(float *audio, int samples)
    {
        // process the samples
        // this part accumulates the 'squares'

        for (int i = 0; i < samples; ++i)
        {
            // get the input sample

            float s = audio[i];

            // remove the oldest value from the sum

            _sum -= *_cursor;

            // calculate the square and write it into the buffer

            double square = s * s;
            *_cursor = square;

            // add it to the sum

            _sum += square;

            // increment the buffer cursor and wrap

            ++_cursor;

            if (_cursor == _integrationBufferEnd)
                _cursor = _integrationBuffer;
        }

        // now calculate the 'root mean' value in db

        return 20 * log10f(_sum / _integrationBufferLength);
    }
};
+2

OpenAL . , , , , .

+1

Source: https://habr.com/ru/post/1779298/


All Articles