关闭

PCM数据合成WAV文件

855人阅读 评论(0) 收藏 举报

由于需要解码后的裸数据保存下来看看效果,故需要将数据合成WAV文件

ypedef struct 
{
    unsigned short  format_tag;
    unsigned short  channels;           /* 1 = mono, 2 = stereo */
    unsigned long   samplerate;         /* typically: 44100, 32000, 22050, 11025 or 8000*/
    unsigned long   bytes_per_second;   /* SamplesPerSec * BlockAlign*/
    unsigned short  blockalign;         /* Channels * (BitsPerSample / 8)*/
    unsigned short  bits_per_sample;    /* 16 or 8 */
} WAVEAUDIOFORMAT;

typedef struct 
{
    char info[4];
    unsigned long length;
} RIFF_CHUNK;


void MuxWAV(LPCTSTR lpPCMFile, LPCTSTR lpDestWavFile, WORD wSampleBits, WORD wChannels, WORD wSamplerate)
{
	CFile FSource;
	BOOL bResult = FSource.Open(lpPCMFile, CFile::modeNoTruncate|CFile::modeRead|CFile::shareExclusive);
	if(bResult == FALSE) return;

	CFile FDest;
	bResult = FDest.Open(lpDestWavFile, CFile::modeCreate|CFile::modeWrite);
	if(bResult == FALSE)
	{
		FSource.Close();
		return;
	}
	
	char* pTempData = new char[10*1024*1024];

    WAVEAUDIOFORMAT format;	
    format.format_tag = 1;
    format.channels = wChannels;
    format.samplerate = wSamplerate;
    format.bits_per_sample = wSampleBits;
    format.blockalign = format.channels * (format.bits_per_sample/8);
    format.bytes_per_second = format.samplerate * format.blockalign;
	FDest.Write("RIFF\0\0\0\0WAVEfmt ", 16);
    int length = 16;
    FDest.Write(&length, 1*sizeof(long));
    FDest.Write(&format, sizeof(format));
    FDest.Write("data\0\0\0\0", sizeof(char)*8); /* Write data chunk */
	
	while(true)
	{
		DWORD dwReadLength = FSource.ReadHuge(pTempData, 10*1024*1024);
		if(dwReadLength == 0) break;
		FDest.WriteHuge(pTempData, dwReadLength);
	}
	
	FSource.Close();
	DWORD dwLength = FDest.GetLength();
	long RiffLen = dwLength - 8;
    long DataLen = dwLength - 44;
	
	FDest.Seek(4, CFile::begin);
	FDest.Write(&RiffLen, sizeof(long));
	FDest.Seek(40, CFile::begin);
	FDest.Write(&DataLen, sizeof(long));
	FDest.Seek(0, CFile::end);
	FDest.Close();
}

顺便提供提取WAV文件中的PCM数据函数

void ExtraWAV(CString& strPath)
{
	HANDLE hRead = ::CreateFile(strPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
	if(!hRead) return;

	const int MBSize = 1024;
	byte buffer[MBSize] = {0};
	DWORD dwReadBytes = 0;
	DWORD dwFileSize = 0;
	GetFileSize(hRead, &dwFileSize);
	DWORD dwReadOffset = 0;
	int err = 0;

	FMT_BLOCK waveBlock;
	RIFF_HEADER riffHeader;
	ReadFile(hRead, &riffHeader, sizeof(riffHeader), &dwReadBytes, NULL);
	if(dwReadBytes != sizeof(riffHeader)) return;

	ReadFile(hRead, &waveBlock, sizeof(waveBlock), &dwReadBytes, NULL);
	if(dwReadBytes != sizeof(waveBlock)) return;

	dwReadOffset += sizeof(RIFF_HEADER) + sizeof(FMT_BLOCK);
	if(waveBlock.dwFmtSize == 0x12)
	{
		ReadFile(hRead, buffer, 2, &dwReadBytes, NULL);
	    if(dwReadBytes != 2) return;
		dwReadOffset += 2;
	}

	ReadFile(hRead, buffer, 4, &dwReadBytes, NULL);
	if(dwReadBytes != 4) return;

	dwReadOffset += sizeof(DWORD);
	DWORD dwDataSize = 0;

	ReadFile(hRead, &dwDataSize, sizeof(dwDataSize), &dwReadBytes, NULL);
	if(dwReadBytes != sizeof(dwDataSize)) return;
	dwReadOffset += sizeof(DWORD);

	int nPos = strPath.ReverseFind('.');
	CString strNewFile;
	DWORD dwIndex = 0;
	strNewFile = strPath.Left(nPos + 1) + _T("pcm");
	while(1)
	{	
		CFile file;
		if(file.Open(strNewFile, CFile::modeRead))
		{
			dwIndex++ ;
			strNewFile.Format(_T("%s~%d.pcm"), strPath.Left(nPos), dwIndex);
			file.Close();
		}
		else
		{
			break;
		}
	}

	HANDLE hWrite = ::CreateFile(strNewFile, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
	if(!hWrite) return;

	HANDLE hFileReadMapping = ::CreateFileMapping(hRead,NULL,PAGE_READONLY, 0, dwFileSize, NULL); 
	if(!hFileReadMapping) 
		err = GetLastError();
	
	HANDLE hFileWriteMapping = ::CreateFileMapping(hWrite,NULL,PAGE_READWRITE, 0, dwDataSize, NULL);
	if(!hFileWriteMapping) 
		err = GetLastError();

	PBYTE pRead = (PBYTE)MapViewOfFile(hFileReadMapping, FILE_MAP_READ, 0, 0, dwFileSize);
	if(!pRead) 
		err = GetLastError();

	PBYTE pWrite = (PBYTE)MapViewOfFile(hFileWriteMapping, FILE_MAP_ALL_ACCESS, 0, 0, dwDataSize);
	if(!pWrite) 
		err = GetLastError();

	memcpy(pWrite, pRead + dwReadOffset, dwDataSize);
	UnmapViewOfFile(pRead);
	UnmapViewOfFile(pWrite);
	CloseHandle(hFileReadMapping);
	CloseHandle(hFileWriteMapping);
	CloseHandle(hRead);
	CloseHandle(hWrite);
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:18177次
    • 积分:384
    • 等级:
    • 排名:千里之外
    • 原创:21篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条
    文章分类
    最新评论