如何将音频字节转换为样本 [英] How to convert audio byte to samples

查看:120
本文介绍了如何将音频字节转换为样本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的结构

/* 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 是原始数据的长度

现在,我想计算每秒的音量,以说出哪一秒的音量最高,哪一秒的音量最低。

I record 10 secs from microphone and waveHeader->lpData has my raw recorded data, and waveHeader->dwBytesRecorded is the raw data's length Now I want to calculate the volume in each second to say which second has highest volume and which one has the lowest.

我知道我应该对绝对值求和并除以样本数量

I know I should sum the absolute values and divide by the number of samples

我使用了 sum + = abs(waveHeader-> lpData [i]); 对于i从0到1秒的数据长度,但效果不佳

I used sum += abs(waveHeader->lpData[i]); for i from 0 to length of one secs data, but it doesn't give me a good result

它始终为我每秒提供相同的结果,但我在几秒钟内保持沉默,并在某些时候说话...

it always gives me the same result for each second, but I am silent in some seconds and speak in some...

我阅读了我必须添加样本,而不是字节 如何将 waveHeader-> lpData [i] 转换为样本?

I read I have to add samples, not bytes How should I convert waveHeader->lpData[i] to samples?

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


推荐答案

您已将WAVEFORMATEX用于捕捉音频,对不对?如果是这样,则可以修改以下例程以满足您的需要:

You have the WAVEFORMATEX used for capturing the audio, right? If so, you can modify the following routine to meet your needs:

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

这篇关于如何将音频字节转换为样本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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