PCM數據轉WAV文件

int simplest_pcm16le_to_wave(const char *pcmpath, int channels, int sample_rate, const char *wavepath)
{
	typedef struct WAVE_HEADER{
		char    fccID[4];       //內容爲""RIFF
		unsigned long dwSize;   //最後填寫,WAVE格式音頻的大小
		char    fccType[4];     //內容爲"WAVE"
	}WAVE_HEADER;

	typedef struct WAVE_FMT{
		char    fccID[4];          //內容爲"fmt "
		unsigned long  dwSize;     //內容爲WAVE_FMT佔的字節數,爲16
		unsigned short wFormatTag; //如果爲PCM,改值爲 1
		unsigned short wChannels;  //通道數,單通道=1,雙通道=2
		unsigned long  dwSamplesPerSec;//採用頻率
		unsigned long  dwAvgBytesPerSec;/* ==dwSamplesPerSec*wChannels*uiBitsPerSample/8 */
		unsigned short wBlockAlign;//==wChannels*uiBitsPerSample/8
		unsigned short uiBitsPerSample;//每個採樣點的bit數,8bits=8, 16bits=16
	}WAVE_FMT;

	typedef struct WAVE_DATA{
		char    fccID[4];       //內容爲"data"
		unsigned long dwSize;   //==NumSamples*wChannels*uiBitsPerSample/8
	}WAVE_DATA;

	int bits = 16;

	WAVE_HEADER pcmHEADER;
	WAVE_FMT    pcmFMT;
	WAVE_DATA   pcmDATA;

	unsigned short m_pcmData;
	FILE *fp, *fpout;

	fp = fopen(pcmpath, "rb+");
	if (fp == NULL)
	{
		printf("Open pcm file error.\n");
		return -1;
	}
	fpout = fopen(wavepath, "wb+");
	if (fpout == NULL)
	{
		printf("Create wav file error.\n");
		return -1;
	}

	/* WAVE_HEADER */
	memcpy(pcmHEADER.fccID, "RIFF", strlen("RIFF"));
	memcpy(pcmHEADER.fccType, "WAVE", strlen("WAVE"));
	fseek(fpout, sizeof(WAVE_HEADER), SEEK_CUR);   //1=SEEK_CUR  ??????

	/* WAVE_FMT */
#if 1
	memcpy(pcmFMT.fccID, "fmt ", strlen("fmt "));
	pcmFMT.dwSize = 16;
	pcmFMT.wFormatTag = 1;
	pcmFMT.wChannels = 1;
	pcmFMT.dwSamplesPerSec = sample_rate;
	pcmFMT.uiBitsPerSample = bits;
	pcmFMT.dwAvgBytesPerSec = pcmFMT.dwSamplesPerSec*pcmFMT.wChannels*pcmFMT.uiBitsPerSample / 8;
	pcmFMT.wBlockAlign = pcmFMT.wChannels*pcmFMT.uiBitsPerSample / 8;
	fwrite(&pcmFMT, sizeof(WAVE_FMT), 1, fpout);  //????????????
#endif

	/* WAVE_DATA */
	memcpy(pcmDATA.fccID, "data", strlen("data"));
	pcmDATA.dwSize = 0;
	fseek(fpout, sizeof(WAVE_DATA), SEEK_CUR);//????????????????????????


	fstream readData(pcmpath, ios::in);
	vector<double>pcmData;
	double dPCMData = 0.0;
	if (readData.is_open())
	{
		string temp = "";
		while (getline(readData, temp))
		{
			if (temp.length() > 1)
			{
				pcmData.push_back(atof(temp.c_str()));
				dPCMData = atof(temp.c_str());
				pcmDATA.dwSize += 2;
				if (dPCMData < 0)
				{
					m_pcmData = dPCMData * 32768;
				}
				else
				{
					m_pcmData = dPCMData * 32767;
				}
				fwrite(&m_pcmData, sizeof(unsigned short), 1, fpout);
			}
		}
	}
	
	//fread(&m_pcmData, sizeof(unsigned short), 1, fp);
	//while (!feof(fp))
	//{
	//	pcmDATA.dwSize += 2;
	//	fwrite(&m_pcmData, sizeof(unsigned short), 1, fpout);
	//	fread(&m_pcmData, sizeof(unsigned short), 1, fp);
	//}

	pcmHEADER.dwSize = 44 + pcmDATA.dwSize;
	rewind(fpout);
	fwrite(&pcmHEADER, sizeof(WAVE_HEADER), 1, fpout);
	fseek(fpout, sizeof(WAVE_FMT), SEEK_CUR);
	fwrite(&pcmDATA, sizeof(WAVE_DATA), 1, fpout);


	fclose(fp);
	fclose(fpout);

	return 0;
}


PCM數據格式:http://blog.csdn.net/ownwell/article/details/8114121/

視音頻數據處理入門:PCM音頻採樣數據處理:http://blog.csdn.net/leixiaohua1020/article/details/50534316


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章