如何根据频率和音量大小生成wav音频文件?

时间:2022-04-29 19:43:27
平台:wince6.0  vs2008 vc++
请教:如何根据频率、音量大小和持续时间,生成wav音频文件。。。wav文件的格式我知道,就是其中的音频数据不知道和频率、音量如何对应的。

void Create(int freq, int volume, int durations)
{
    。。。。
}

5 个解决方案

#1


补充:比如我要生成1段1KHZ,音量为80,持续500ms的wav文件,该怎么编写音频数据格式??
补充:比如我要生成1段1KHZ,音量为80,持续500ms的wav文件,该怎么编写音频数据格式??
补充:比如我要生成1段1KHZ,音量为80,持续500ms的wav文件,该怎么编写音频数据格式??

#2


我没太明白你什么意思
你什么基础数据都没有
楞写一个wav文件出来?

#3


引用 2 楼  的回复:
我没太明白你什么意思
你什么基础数据都没有
楞写一个wav文件出来?


就是写函数生成一个wav文件,相当于能发出像Beep(freq, durations)的声音。

#4


可以根据sin波形生成wav文件:

#define WAVE_HEAD_LENGTH 44 //wav头文件长度
//.wav文件的文件头结构
typedef struct
{
char chRIFF[4];
DWORD dwRIFFLen;
char chWAVE[4];
char chFMT[4];
DWORD dwFMTLen;
PCMWAVEFORMAT pwf;
char chDATA[4];
DWORD dwDATALen;
//UINT8* pBufer;
}WaveHeader;

//生成wav文件:单通道、8bit、44.1KHZ
BOOL CWaveFunction::Create(int freq, int volume, int durations)
{
DWORD totalLen = (m_samplefreq * m_channels * m_channelbits / 8) * durations / 1000 + 44; //文件总长度=(采样率 * 通道数 * 比特数 / 8) * 持续时间(s)
pHeader->chRIFF[0] = 'R';
pHeader->chRIFF[1] = 'I';
pHeader->chRIFF[2] = 'F';
pHeader->chRIFF[3] = 'F';
pHeader->dwRIFFLen = totalLen - 8; //文件的总长度-8bits

pHeader->chWAVE[0] = 'W';
pHeader->chWAVE[1] = 'A';
pHeader->chWAVE[2] = 'V';
pHeader->chWAVE[3] = 'E';

pHeader->chFMT[0] = 'f';
pHeader->chFMT[1] = 'm';
pHeader->chFMT[2] = 't';
pHeader->chFMT[3] = ' ';

pHeader->dwFMTLen = 0x0010; //一般情况下Size为16,如果为18则最后多了2个字节的附加信息
pHeader->pwf.wf.wFormatTag = 0x0001; //编码方式
pHeader->pwf.wf.nChannels = m_channels; //1为单通道,2为双通道
pHeader->pwf.wf.nSamplesPerSec = m_samplefreq; //=44.1KHz
pHeader->pwf.wf.nAvgBytesPerSec = m_samplefreq * m_channels * m_channelbits / 8; //每秒所需字节数
pHeader->pwf.wf.nBlockAlign = 0x0002; //一次处理多个该值大小的字节数据
pHeader->pwf.wBitsPerSample = m_channelbits; //16位,即设置PCM的方式为16位立体声(双通道)

pHeader->chDATA[0] = 'd';
pHeader->chDATA[1] = 'a';
pHeader->chDATA[2] = 't';
pHeader->chDATA[3] = 'a';
pHeader->dwDATALen = totalLen - WAVE_HEAD_LENGTH; //数据的长度,=文件总长度-头长度(44bit)

if(pWaveBufer!=NULL)
delete pWaveBufer;
pWaveBufer = new char[pHeader->dwRIFFLen + 8]; //音频数据
memcpy(pWaveBufer, pHeader, WAVE_HEAD_LENGTH);

MakeWaveData(pHeader->pwf.wf.nSamplesPerSec, freq, volume, pWaveBufer + WAVE_HEAD_LENGTH, pHeader->dwDATALen);
CFile m_file;
CFileException fileException;
CString m_csFileName= _T("\\NandFlash\\111.wav");//保存路径
m_file.Open(m_csFileName,CFile::modeCreate|CFile::modeReadWrite, &fileException);
m_file.SeekToBegin();
//m_file.Write(pHeader, 44);
m_file.Write(pWaveBufer, pHeader->dwRIFFLen + 8);
m_file.Seek(pHeader->dwDATALen,CFile::begin);
m_file.Close();


return TRUE;
}

void CWaveFunction::MakeWaveData(int rate, int freq, int amp, char* p, int len)
{
if(m_channelbits == 16) //16位
{
for(int i = 0; i < len; i+=2)
{
INT32 v = (INT32)(sin((len - i) * (MATH_PI * 2) / rate * freq) * amp * 32768 / 100 + 32768);
*(p + i) = (v & 0x00FF); //低字节在前
*(p + i + 1) = ((v >> 4) & 0xFF); //高字节在后
}

}
else if(m_channelbits == 8)
{
for(int i = 0; i < len; i+=1)
{
*(p + i) = sin((len - i) * (MATH_PI * 2) / rate * freq) * amp * 128 / 100 + 128;
}
}
}

#5


为什么我运行的时候出现这个错误呢:“DAN2.C(6): error C141: syntax error near 'DWORD'”

#1


补充:比如我要生成1段1KHZ,音量为80,持续500ms的wav文件,该怎么编写音频数据格式??
补充:比如我要生成1段1KHZ,音量为80,持续500ms的wav文件,该怎么编写音频数据格式??
补充:比如我要生成1段1KHZ,音量为80,持续500ms的wav文件,该怎么编写音频数据格式??

#2


我没太明白你什么意思
你什么基础数据都没有
楞写一个wav文件出来?

#3


引用 2 楼  的回复:
我没太明白你什么意思
你什么基础数据都没有
楞写一个wav文件出来?


就是写函数生成一个wav文件,相当于能发出像Beep(freq, durations)的声音。

#4


可以根据sin波形生成wav文件:

#define WAVE_HEAD_LENGTH 44 //wav头文件长度
//.wav文件的文件头结构
typedef struct
{
char chRIFF[4];
DWORD dwRIFFLen;
char chWAVE[4];
char chFMT[4];
DWORD dwFMTLen;
PCMWAVEFORMAT pwf;
char chDATA[4];
DWORD dwDATALen;
//UINT8* pBufer;
}WaveHeader;

//生成wav文件:单通道、8bit、44.1KHZ
BOOL CWaveFunction::Create(int freq, int volume, int durations)
{
DWORD totalLen = (m_samplefreq * m_channels * m_channelbits / 8) * durations / 1000 + 44; //文件总长度=(采样率 * 通道数 * 比特数 / 8) * 持续时间(s)
pHeader->chRIFF[0] = 'R';
pHeader->chRIFF[1] = 'I';
pHeader->chRIFF[2] = 'F';
pHeader->chRIFF[3] = 'F';
pHeader->dwRIFFLen = totalLen - 8; //文件的总长度-8bits

pHeader->chWAVE[0] = 'W';
pHeader->chWAVE[1] = 'A';
pHeader->chWAVE[2] = 'V';
pHeader->chWAVE[3] = 'E';

pHeader->chFMT[0] = 'f';
pHeader->chFMT[1] = 'm';
pHeader->chFMT[2] = 't';
pHeader->chFMT[3] = ' ';

pHeader->dwFMTLen = 0x0010; //一般情况下Size为16,如果为18则最后多了2个字节的附加信息
pHeader->pwf.wf.wFormatTag = 0x0001; //编码方式
pHeader->pwf.wf.nChannels = m_channels; //1为单通道,2为双通道
pHeader->pwf.wf.nSamplesPerSec = m_samplefreq; //=44.1KHz
pHeader->pwf.wf.nAvgBytesPerSec = m_samplefreq * m_channels * m_channelbits / 8; //每秒所需字节数
pHeader->pwf.wf.nBlockAlign = 0x0002; //一次处理多个该值大小的字节数据
pHeader->pwf.wBitsPerSample = m_channelbits; //16位,即设置PCM的方式为16位立体声(双通道)

pHeader->chDATA[0] = 'd';
pHeader->chDATA[1] = 'a';
pHeader->chDATA[2] = 't';
pHeader->chDATA[3] = 'a';
pHeader->dwDATALen = totalLen - WAVE_HEAD_LENGTH; //数据的长度,=文件总长度-头长度(44bit)

if(pWaveBufer!=NULL)
delete pWaveBufer;
pWaveBufer = new char[pHeader->dwRIFFLen + 8]; //音频数据
memcpy(pWaveBufer, pHeader, WAVE_HEAD_LENGTH);

MakeWaveData(pHeader->pwf.wf.nSamplesPerSec, freq, volume, pWaveBufer + WAVE_HEAD_LENGTH, pHeader->dwDATALen);
CFile m_file;
CFileException fileException;
CString m_csFileName= _T("\\NandFlash\\111.wav");//保存路径
m_file.Open(m_csFileName,CFile::modeCreate|CFile::modeReadWrite, &fileException);
m_file.SeekToBegin();
//m_file.Write(pHeader, 44);
m_file.Write(pWaveBufer, pHeader->dwRIFFLen + 8);
m_file.Seek(pHeader->dwDATALen,CFile::begin);
m_file.Close();


return TRUE;
}

void CWaveFunction::MakeWaveData(int rate, int freq, int amp, char* p, int len)
{
if(m_channelbits == 16) //16位
{
for(int i = 0; i < len; i+=2)
{
INT32 v = (INT32)(sin((len - i) * (MATH_PI * 2) / rate * freq) * amp * 32768 / 100 + 32768);
*(p + i) = (v & 0x00FF); //低字节在前
*(p + i + 1) = ((v >> 4) & 0xFF); //高字节在后
}

}
else if(m_channelbits == 8)
{
for(int i = 0; i < len; i+=1)
{
*(p + i) = sin((len - i) * (MATH_PI * 2) / rate * freq) * amp * 128 / 100 + 128;
}
}
}

#5


为什么我运行的时候出现这个错误呢:“DAN2.C(6): error C141: syntax error near 'DWORD'”