Как преобразовать аудио байт в сэмплы - PullRequest
2 голосов
/ 08 апреля 2019

Это моя структура

/* wave data block header */
typedef struct wavehdr_tag {
    LPSTR       lpData;                 /* pointer to locked data buffer */
    DWORD       dwBufferLength;         /* length of data buffer */
    DWORD       dwBytesRecorded;        /* used for input only */
    DWORD_PTR   dwUser;                 /* for client's use */
    DWORD       dwFlags;                /* assorted flags (see defines) */
    DWORD       dwLoops;                /* loop control counter */
    struct wavehdr_tag FAR *lpNext;     /* reserved for driver */
    DWORD_PTR   reserved;               /* reserved for driver */
} WAVEHDR, *PWAVEHDR, NEAR *NPWAVEHDR, FAR *LPWAVEHDR;

У меня есть эта переменная WAVEHDR waveHeader;

Я записываю 10 секунд с микрофона, и waveHeader->lpData содержит мои необработанные записанные данные, а waveHeader->dwBytesRecorded - длину необработанных данных. Теперь я хочу вычислить громкость в каждую секунду, чтобы сказать, какая из секунд имеет наибольшую громкость, а какая - самую низкую.

Я знаю, что должен суммировать абсолютные значения и делить на количество выборок

Я использовал sum += abs(waveHeader->lpData[i]); для i от 0 до длины данных в одну секунду, но это не дает хорошего результата

это всегда дает мне один и тот же результат каждую секунду, но я молчу через несколько секунд и говорю в некоторых ...

Я прочитал Я должен добавить образцы, а не байты Как мне преобразовать waveHeader->lpData[i] в образцы?

//len = length of one secs data (waveHeader->dwBytesRecorded/10)
for (int i=0; i<len; i++)
{
    sum += abs(waveHeader->lpData[i]);
}

1 Ответ

1 голос
/ 10 апреля 2019

У вас есть WAVEFORMATEX, используемый для захвата аудио, верно? Если это так, вы можете изменить следующую процедуру для удовлетворения ваших потребностей:

void ProcessSamples(WAVEHDR* header, WAVEFORMATEX* format)
{
    BYTE* pData = (BYTE*)(header->data);
    DWORD dwNumSamples = header->dwBytesRecorded / format->nBlockAlign;

    // 16-bit stereo, the most common format
    if ((format->wBitsPerSample == 16) && (format->nChannels == 2))
    {
        for (DWORD index = 0; index < dwNumSamples; index++)
        {
            short left = *(short*)pData; pData+=2;
            short right = *(short*)pData; pData+=2;
        }
    }
    else if ((format->wBitsPerSample == 16) && (format->nChannels == 1))
    {
        for (DWORD index = 0; index < dwNumSamples; index++)
        {
            short monoSample = *(short*)pData; pData+=2;
        }
    }
    else if ((format->wBitsPerSample == 8) && (format->nChannels == 2))
    {
        // 8-bit samples are unsigned.
        // "128" is the median silent value
        // normalize to a "signed" value
        for (DWORD index = 0; index < dwNumSamples; index++)
        {
            signed char left = (*(signed char*)pData) - 128; pData += 1;
            signed char right = (*(signed char*)pData) - 128; pData += 1;
        }
    }
    else if ((format->wBitsPerSample == 8) && (format->nChannels == 1))
    {
        for (DWORD index = 0; index < dwNumSamples; index++)
        {
            signed char monosample = (*(signed char*)pData) - 128; pData += 1;
        }
    }
}
...