在iOS上录制,修改和播放音频 [英] Recording, modifying and playing audio on iOS

查看:134
本文介绍了在iOS上录制,修改和播放音频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:最后,我完全按照下面的说明使用,AVRecorder用于录制语音,openAL用于音高移位和播放。它运作得很好。

In the end I used exactly as I explained below, AVRecorder for recording the speech and openAL for the pitch shift and playback. It worked out quite well.

我有一个关于录制,修改和播放音频的问题。之前我问了一个类似的问题(记录,修改在iOS上实时播放和播放音频)但我现在有更多的信息,可以提供一些进一步的建议。

I got a question regarding recording, modifying and playing back audio. I asked a similar question before ( Record, modify pitch and play back audio in real time on iOS ) but I now have more information and could do with some further advice please.

所以首先这是什么我正在尝试(在主线程的单独线程上):

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


  1. 监听iphone麦克风

  2. 检查大于某一音量的声音

  3. 如果超过阈值开始录音,例如此人开始说话

  4. 继续记录,直到音量降至阈值以下,例如人不再说话

  5. 修改录制声音的音高。

  6. 播放声音

  1. monitor the iphone mic
  2. check for sound greater than a certain volume
  3. if above threshold start recording e.g. person starts talking
  4. continue to record until volume drops below threshold e.g. person stops talking
  5. modify pitch of recorded sound.
  6. playback sound

我正在考虑使用AVRecorder来监听和录制声音,这里有一个很好的教程: http://mobileorchard.com/tutorial-detecting-when-a-user-blows-into-the-mic/

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

我正在考虑使用openAL修改录制音频的音高。

and I was thinking of using openAL to modify the pitch of the recorded audio.

所以我的问题是,我的想法是正确的上面的点列表,我错过了什么或有更好/更简单的方法来做到这一点。我可以避免混合使用音频库,也可以使用AVFoundation来改变音高吗?

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

推荐答案

您可以使用AVRecorder或类似的东西实时IO音频单元。

You can either use AVRecorder or something lower like the realtime IO audio unit.

'音量'的概念非常模糊。您可能希望了解计算峰值和RMS值之间的差异,并了解如何在给定时间内整合RMS值(例如300米,这是VU仪表使用的值)。

The concept of 'volume' is pretty vague. You might want to look at the difference between calculating peak and RMS values, and understanding how to integrate an RMS value over a given time (say 300ms which is what a VU meter uses).

基本上你总结了值的所有平方。您可以使用平方根并使用10 * log10f(sqrt(sum / num_samples))转换为dBFS,但是您可以使用20 * log10f(sum / num_samples)在没有sqrt的情况下执行此操作。

Basically you sum all the squares of the values. You would take the square root and convert to dBFS with 10 * log10f(sqrt(sum/num_samples)), but you can do that without the sqrt in one step with 20 * log10f(sum/num_samples).

你需要做很多调整积分时间和阈值才能让它按照你想要的方式运行。

You'll need to do a lot of adjusting of integration times and thresholds to get it to behave the way you want.

For音高变换,我认为OpenAL有诀窍,其背后的技术称为带限插值 - https://ccrma.stanford.edu/~jos/resample/Theory_Ideal_Bandlimited_Interpolation.html

For pitch shifting, I think OpenAL with do the trick, the technique behind it is called band limited interpolation - https://ccrma.stanford.edu/~jos/resample/Theory_Ideal_Bandlimited_Interpolation.html

此示例将rms计算显示为运行平均值。循环缓冲区保持正方形的历史,并且无需对每个操作求和。我没有运行它所以把它当作伪代码;)

This example shows a rms calculation as a running average. The circular buffer maintains a history of squares, and eliminates the need to sum the squares every operation. I haven't run it so treat it as pseudo code ;)

示例:

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

这篇关于在iOS上录制,修改和播放音频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆