如何將資料寫入去檔頭???? |
答題得分者是:Windyboy
|
mtmkid
一般會員 發表:17 回覆:19 積分:7 註冊:2004-04-12 發送簡訊給我 |
若要播放去擋頭的WAV檔,就必須將前44BYTE的資料寫回到去檔頭中...
還必須將當初WAV檔的格式如幾聲道獲取樣頻率多少等...
相同的格式寫入去檔頭中才可順利播放... 小弟我目前卡在不知將如何把資料寫回到去檔頭中.....
比方我要開啟一個test.pcm的去檔頭檔案...他原本格式是
取樣頻率48000,單聲道,Reolution=16BIT
該如何還原呢??? 小弟我找到這個程式碼
//變數宣告
DWORD SizeOfFile;
DWORD SizeWaveChunk;
WORD WaveTypeFormat; //PCM.
WORD MonoStereo; //0x01 Mono. 0x02 Stereo.
DWORD SampleRate;
DWORD BytesSample;
WORD BlockAlignment;
WORD BitsSample;
DWORD SizeDataChunk;
DWORD Temp; //lpNumberOfBytesWritten.
WORD nDataChunks; //Sample numbers.
DWORD SizeOfData; //The size of real WAV data.
DWORD SizeChunk; //(one)Sample width.
SaveToFile(AnsiString SaveFileName)
{
HANDLE HFile; //Create a waveform audio file.
HFile=CreateFile(SaveFileName.c_str(),
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL); if(HFile==INVALID_HANDLE_VALUE)
throw("Error on CreateFile"); //Define the file format is waveform audio
WriteFile(HFile,"RIFF",4,&Temp,NULL); //0~3 Byte m_SizeOfFile=44 nDataChunks*2-8; WriteFile(HFile,&SizeOfFile,4,&Temp,NULL); //4~7 Byte
WriteFile(HFile,"WAVE",4,&Temp,NULL); //8~11 Byte //Waveform format
WriteFile(HFile,"fmt ",4,&Temp,NULL); //12~15 Byte
WriteFile(HFile,&SizeWaveChunk,4,&Temp,NULL); //16~19 Byte
WriteFile(HFile,&WaveTypeFormat,2,&Temp,NULL); //20~12 Byte
WriteFile(HFile,&MonoStereo,2,&Temp,NULL); //22~23 Byte
WriteFile(HFile,&SampleRate,4,&Temp,NULL); //24~27 Byte
WriteFile(HFile,&BytesSample,4,&Temp,NULL); //28~31 Byte
WriteFile(HFile,&BlockAlignment,2,&Temp,NULL); //32~33 Byte
WriteFile(HFile,&BitsSample,2,&Temp,NULL); //34~35 Byte //Waveform data size
WriteFile(HFile,"data",4,&Temp,NULL); //36~39 Byte SizeOfData=nDataChunks*2; WriteFile(HFile,&SizeOfData,4,&Temp,NULL); //40~43 Byte //寫入音訊資料段(44~ Byte)
WriteFile(m_HFile,WaveData,SizeOfData,&Temp,NULL); CloseHandle(HFile);
}
是由koni前輩提供的...但是我編譯時會出現錯誤說....
不知該如何解決呢....小弟這問題可能很蠢...
但是這真的困擾我很久了說...
|
Windyboy
版主 發表:7 回覆:119 積分:210 註冊:2002-11-07 發送簡訊給我 |
引言: 若要播放去擋頭的WAV檔,就必須將前44BYTE的資料寫回到去檔頭中... 還必須將當初WAV檔的格式如幾聲道獲取樣頻率多少等... 相同的格式寫入去檔頭中才可順利播放... 小弟我目前卡在不知將如何把資料寫回到去檔頭中..... 比方我要開啟一個test.pcm的去檔頭檔案...他原本格式是 取樣頻率48000,單聲道,Reolution=16BIT 該如何還原呢??? 小弟我找到這個程式碼 //變數宣告 DWORD SizeOfFile; DWORD SizeWaveChunk; WORD WaveTypeFormat; //PCM. WORD MonoStereo; //0x01 Mono. 0x02 Stereo. DWORD SampleRate; DWORD BytesSample; WORD BlockAlignment; WORD BitsSample; DWORD SizeDataChunk; DWORD Temp; //lpNumberOfBytesWritten. WORD nDataChunks; //Sample numbers. DWORD SizeOfData; //The size of real WAV data. DWORD SizeChunk; //(one)Sample width. SaveToFile(AnsiString SaveFileName) { HANDLE HFile; //Create a waveform audio file. HFile=CreateFile(SaveFileName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(HFile==INVALID_HANDLE_VALUE) throw("Error on CreateFile"); //Define the file format is waveform audio WriteFile(HFile,"RIFF",4,&Temp,NULL); //0~3 Byte m_SizeOfFile=44 nDataChunks*2-8; WriteFile(HFile,&SizeOfFile,4,&Temp,NULL); //4~7 Byte WriteFile(HFile,"WAVE",4,&Temp,NULL); //8~11 Byte //Waveform format WriteFile(HFile,"fmt ",4,&Temp,NULL); //12~15 Byte WriteFile(HFile,&SizeWaveChunk,4,&Temp,NULL); //16~19 Byte WriteFile(HFile,&WaveTypeFormat,2,&Temp,NULL); //20~12 Byte WriteFile(HFile,&MonoStereo,2,&Temp,NULL); //22~23 Byte WriteFile(HFile,&SampleRate,4,&Temp,NULL); //24~27 Byte WriteFile(HFile,&BytesSample,4,&Temp,NULL); //28~31 Byte WriteFile(HFile,&BlockAlignment,2,&Temp,NULL); //32~33 Byte WriteFile(HFile,&BitsSample,2,&Temp,NULL); //34~35 Byte //Waveform data size WriteFile(HFile,"data",4,&Temp,NULL); //36~39 Byte SizeOfData=nDataChunks*2; WriteFile(HFile,&SizeOfData,4,&Temp,NULL); //40~43 Byte //寫入音訊資料段(44~ Byte) WriteFile(m_HFile,WaveData,SizeOfData,&Temp,NULL); CloseHandle(HFile); } 是由koni前輩提供的...但是我編譯時會出現錯誤說.... 不知該如何解決呢....小弟這問題可能很蠢... 但是這真的困擾我很久了說...將紅色部份的Code拿掉, 再將你的PCM音訊資料讀入WaveData, 就可以了^_^ WaveData應該是宣告為 Byte WaveData; 使用TFileStream或fopen都可以將你的PCM音訊資料讀入. -------------------------- ~天下本無事 庸人自擾之~ |
mtmkid
一般會員 發表:17 回覆:19 積分:7 註冊:2004-04-12 發送簡訊給我 |
我在這邊也出現錯誤說
SaveToFile(AnsiString SaveFileName)
謝謝你的回應 //變數宣告
DWORD SizeOfFile;
DWORD SizeWaveChunk;
WORD WaveTypeFormat; //PCM.
WORD MonoStereo; //0x01 Mono. 0x02 Stereo.
DWORD SampleRate;
DWORD BytesSample;
WORD BlockAlignment;
WORD BitsSample;
DWORD SizeDataChunk;
DWORD Temp; //lpNumberOfBytesWritten.
WORD nDataChunks; //Sample numbers.
DWORD SizeOfData; //The size of real WAV data.
DWORD SizeChunk; //(one)Sample width.
SaveToFile(AnsiString SaveFileName)
{
HANDLE HFile; //Create a waveform audio file.
HFile=CreateFile(SaveFileName.c_str(),
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL); if(HFile==INVALID_HANDLE_VALUE)
throw("Error on CreateFile"); //Define the file format is waveform audio
WriteFile(HFile,"RIFF",4,&Temp,NULL); //0~3 Byte m_SizeOfFile=44 nDataChunks*2-8; WriteFile(HFile,&SizeOfFile,4,&Temp,NULL); //4~7 Byte
WriteFile(HFile,"WAVE",4,&Temp,NULL); //8~11 Byte //Waveform format
WriteFile(HFile,"fmt ",4,&Temp,NULL); //12~15 Byte
WriteFile(HFile,&SizeWaveChunk,4,&Temp,NULL); //16~19 Byte
WriteFile(HFile,&WaveTypeFormat,2,&Temp,NULL); //20~12 Byte
WriteFile(HFile,&MonoStereo,2,&Temp,NULL); //22~23 Byte
WriteFile(HFile,&SampleRate,4,&Temp,NULL); //24~27 Byte
WriteFile(HFile,&BytesSample,4,&Temp,NULL); //28~31 Byte
WriteFile(HFile,&BlockAlignment,2,&Temp,NULL); //32~33 Byte
WriteFile(HFile,&BitsSample,2,&Temp,NULL); //34~35 Byte //Waveform data size
WriteFile(HFile,"data",4,&Temp,NULL); //36~39 Byte SizeOfData=nDataChunks*2; WriteFile(HFile,&SizeOfData,4,&Temp,NULL); //40~43 Byte //寫入音訊資料段(44~ Byte)
WriteFile(m_HFile,WaveData,SizeOfData,&Temp,NULL); CloseHandle(HFile);
}
|
Windyboy
版主 發表:7 回覆:119 積分:210 註冊:2002-11-07 發送簡訊給我 |
|
mtmkid
一般會員 發表:17 回覆:19 積分:7 註冊:2004-04-12 發送簡訊給我 |
對不起喔!!表達的不清楚....真是抱歉
小弟我寫了一個錄音程式可錄成WAV檔案和去檔頭的PCM檔案
去檔頭的PCM檔案就是把WAV檔的前44Byte刪掉所產生的... 而現在我想要播放PCM檔案就必須把刪掉的44Byte寫回來才可播放....
我的問題卡在該如何將這44Byte寫回來呢???
這44Byte,某段落位元中都代表著原本WAV檔案的格式
比如說22~23Byte是代表單聲或立體聲...
我該如何將這44Byte的資料依序寫回到PCM檔案中呢???
不知道該怎麼下手說!!!!
|
Windyboy
版主 發表:7 回覆:119 積分:210 註冊:2002-11-07 發送簡訊給我 |
|
mtmkid
一般會員 發表:17 回覆:19 積分:7 註冊:2004-04-12 發送簡訊給我 |
|
Windyboy
版主 發表:7 回覆:119 積分:210 註冊:2002-11-07 發送簡訊給我 |
|
mtmkid
一般會員 發表:17 回覆:19 積分:7 註冊:2004-04-12 發送簡訊給我 |
|
Windyboy
版主 發表:7 回覆:119 積分:210 註冊:2002-11-07 發送簡訊給我 |
你的問題不是SaveToFile這個Func有問題, 而是呼叫的問題, 例如你在Form1下Button1的Click事件中呼叫 那你SaveToFile的函式原型就要放在Click事件的上面, 意思就是要在你呼叫SaveToFile之前先宣告 或者是把SaveToFile改成 TForm1::SaveToFile(AnsiString SaveFileName)
{
} 在.h檔裡加一行 public: SaveToFile(AnsiString SaveFileName); 讓SaveToFile變成Form1的成員函式 就不會出現那些Error了 幫忙是應該的啦...哪天我搞不好也需要你的幫忙^^ 互相囉:) --------------------------
~天下本無事 庸人自擾之~
|
mtmkid
一般會員 發表:17 回覆:19 積分:7 註冊:2004-04-12 發送簡訊給我 |
|
Windyboy
版主 發表:7 回覆:119 積分:210 註冊:2002-11-07 發送簡訊給我 |
這是我測OK的Code,試試看吧! .cpp
===============================================
//--------------------------------------------------------------------------- #include.h ===================================================== //--------------------------------------------------------------------------- #ifndef Unit1H #define Unit1H //--------------------------------------------------------------------------- #include |
mtmkid
一般會員 發表:17 回覆:19 積分:7 註冊:2004-04-12 發送簡訊給我 |
原來是這樣子的阿,突然覺得我自己好蠢喔...< >< >
目前已經可以順利RUN這個程式了
但是產生的WAV檔怎麼不能播放呢???
是不是這些變數要給他數值呢??/
DWORD SizeOfFile;
DWORD SizeWaveChunk;
WORD WaveTypeFormat; //PCM.
WORD MonoStereo=1; //0x01 Mono. 0x02 Stereo.
DWORD SampleRate;
DWORD BytesSample;
WORD BlockAlignment;
WORD BitsSample;
DWORD SizeDataChunk;
DWORD Temp; //lpNumberOfBytesWritten.
WORD nDataChunks; //Sample numbers.
DWORD SizeOfData; //The size of real WAV data.
DWORD SizeChunk; //(one)Sample width.
不知道是不是呢???
感激
|
Windyboy
版主 發表:7 回覆:119 積分:210 註冊:2002-11-07 發送簡訊給我 |
|
mtmkid
一般會員 發表:17 回覆:19 積分:7 註冊:2004-04-12 發送簡訊給我 |
DWORD SizeOfFile; //4~7 Byte檔案總長度
DWORD SizeWaveChunk=16; //16~19 Byte說明資料結構PCMWAVEFORMAT的大小,我給他的值為16
WORD WaveTypeFormat=1;//20~12Byte wave檔的聲音檔格式,我給他的值為1
WORD MonoStereo=1; //22~23Byte聲音幾聲道1為單聲2為立體聲,給1
DWORD SampleRate=48000;//24~27 Byte每秒的取樣數,給48000
DWORD BytesSample=48000;//28~31 Byte每秒資料量,給48000
WORD BlockAlignment=1;//32~33 Byte區塊大小,給1
WORD BitsSample=8;//34~35 Byte取樣位元數,給8
DWORD SizeDataChunk;//40~43 Byte檔案大小
DWORD Temp; //lpNumberOfBytesWritten.
WORD nDataChunks; //Sample numbers.
DWORD SizeOfData; //The size of real WAV data.
DWORD SizeChunk; //(one)Sample width. 不知道是不是這樣給數值呢???
其中檔案總長度和檔案大小該如何得知呢???
去檔頭中的資料已被刪掉該從何得知呢???
這四各變數該給什麼數值呢???我不清楚做什麼用的說??
DWORD Temp; //lpNumberOfBytesWritten.
WORD nDataChunks; //Sample numbers.
DWORD SizeOfData; //The size of real WAV data.
DWORD SizeChunk; //(one)Sample width.
煩請前輩在幫我解惑!!!感激!!
|
Windyboy
版主 發表:7 回覆:119 積分:210 註冊:2002-11-07 發送簡訊給我 |
Hi mtmkid: 我覺得你應該自己再去多查點資料, 先將觀念建立好, 這樣你就會知道WAVE的檔頭該放什麼東西, 哪些變數該於什麼樣的數值你自己就會一清二楚, 不是我不回答你, 只是我覺得這些東西是查一下資料就會做的出來的, 也不用問人, 試著做出一個WAVE檔後, 播放看看就知道對不對了, 網路真的是什麼都有, Google真的是超好用,^_______^ 千萬不要怪我不回答你的問題啊~~ 我只是覺得這樣對你比較好^^ 最後再補充一句, 就是 單單有PCM的資料, 要怎麼得知它原來的Sample Rate等等的資料, 我還真不知道呢@.@? --------------------------
~天下本無事 庸人自擾之~
|
mtmkid
一般會員 發表:17 回覆:19 積分:7 註冊:2004-04-12 發送簡訊給我 |
成功了!!!總算是成功了!!
真是太感謝Windyboy版大用心良苦了....總算靠自己的力量解決了問題!!!
m_SizeOfFile=44+nDataChunks*2-8;
SizeOfData=nDataChunks*2;
仔細研究這兩行的用意總算了解
原來是利用去檔頭的檔案大小除以取樣頻率數 程式修改如下
我將它改成可自選讀某一個去檔頭的WAV檔.....
但是現在第一次讀去檔頭時順利改成WAV檔
第二次在讀去檔頭檔案時就出現錯誤了說....
if(HFile==INVALID_HANDLE_VALUE)
throw("Error on CreateFile");
不知道是什麼原因耶,困惑了我許久說....
SaveToFile(AnsiString SaveFileName) { HANDLE HFile; //Create a waveform audio file. HFile=CreateFile(SaveFileName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(HFile==INVALID_HANDLE_VALUE) throw("Error on CreateFile"); //Define the file format is waveform audio WriteFile(HFile,"RIFF",4,&Temp,NULL); //0~3 Byte SizeOfFile=44 SampleRate*SizeChunk-8; WriteFile(HFile,&SizeOfFile,4,&Temp,NULL); //4~7 Byte WriteFile(HFile,"WAVE",4,&Temp,NULL); //8~11 Byte //Waveform format WriteFile(HFile,"fmt ",4,&Temp,NULL); //12~15 Byte WriteFile(HFile,&SizeWaveChunk,4,&Temp,NULL); //16~19 Byte WriteFile(HFile,&WaveTypeFormat,2,&Temp,NULL); //20~12 Byte WriteFile(HFile,&MonoStereo,2,&Temp,NULL); //22~23 Byte WriteFile(HFile,&SampleRate,4,&Temp,NULL); //24~27 Byte WriteFile(HFile,&BytesSample,4,&Temp,NULL); //28~31 Byte WriteFile(HFile,&BlockAlignment,2,&Temp,NULL); //32~33 Byte WriteFile(HFile,&BitsSample,2,&Temp,NULL); //34~35 Byte //Waveform data size WriteFile(HFile,"data",4,&Temp,NULL); //36~39 Byte SizeOfData=SampleRate*SizeChunk; WriteFile(HFile,&SizeOfData,4,&Temp,NULL); //40~43 Byte //寫入音訊資料段(44~ Byte) WriteFile(HFile,WaveData,SizeOfData,&Temp,NULL); CloseHandle(HFile); } //--------------------------------------------------------------------------- void __fastcall TForm1::OpenpcmExecute(TObject *Sender) { OpenDialog1->Filter="去檔頭(*.pcm)|*.pcm"; if (OpenDialog1->Execute()==true) { File_name=OpenDialog1->FileName; PCM->ShowModal(); TFileStream *fsPCM = new TFileStream(OpenDialog1->FileName, fmOpenRead); WaveData = new BYTE[fsPCM->Size]; SizeDataChunk=fsPCM->Size; SizeChunk=SizeDataChunk/SampleRate; fsPCM->Read(WaveData, fsPCM->Size); SaveToFile("C:\\t.wav"); delete WaveData; delete fsPCM; } } //--------------------------------------------------------------------------- |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |