簡體   English   中英

在iOS上錄制,修改和播放音頻

[英]Recording, modifying and playing audio on iOS

編輯:最后,我完全按照下面的說明使用AVRecorder來記錄語音和openAL來進行音調轉換和播放。 效果很好。

我有一個關於錄制,修改和播放音頻的問題。 之前我問過一個類似的問題( 在iOS上實時記錄,修改音高和播放音頻 ),但是我現在有更多信息,可以提供一些其他建議。

所以首先這是我要做的(在與主線程不同的線程上):

  1. 監控iPhone麥克風
  2. 檢查聲音是否大於一定音量
  3. 如果超過閾值,則開始記錄,例如,人開始講話
  4. 繼續記錄,直到音量降至閾值以下,例如,人停止說話
  5. 修改錄制聲音的音高。
  6. 播放聲音

我當時正在考慮使用AVRecorder來監視和錄制聲音,這里的好教程: http : //mobileorchard.com/tutorial-detecting-when-a-user-blows-into-the-mic/

我當時在考慮使用openAL修改錄制音頻的音高。

所以我的問題是,我的想法在上述幾點中是正確的嗎?我是否缺少某些東西,或者有更好/更容易的方法來做到這一點? 我是否可以避免混合音頻庫,而僅使用AVFoundation來改變音調?

您可以使用AVRecorder或其他諸如實時IO音頻單元之類的東西。

“體積”的概念非常模糊。 您可能需要查看計算峰值和RMS值之間的差異,並了解如何在給定時間內積分RMS值(例如,VU儀表使用300ms)。

基本上,您將所有值的平方求和。 您可以取平方根,並使用10 * log10f(sqrt(sum / num_samples))轉換為dBFS,但是您可以在沒有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);
    }
};

OpenAL重采樣會反過來改變音高和持續時間。 例如,重新采樣到較高音高的聲音將播放較短的時間,因此播放速度更快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM