全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2623
推到 Plurk!
推到 Facebook!

wav檔的合併存檔播放

缺席
mine
中階會員


發表:28
回覆:129
積分:56
註冊:2004-03-31

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-05-26 16:06:13 IP:61.221.xxx.xxx 未訂閱
procedure TForm1.Button1Click(Sender: TObject); var wav1:TMemorystream; bBuf:Integer; i:integer; wavlen,countlen:int64; buffer:array[0..300000] of Byte; begin for i:=0 to 300000 do begin  buffer[i]:=0 end; bBuf:=0; wav1:=TmemoryStream.Create; Wav1.LoadFromFile('c:\program files\cmmsvc\voice\201.wav'); wavlen:=wav1.Size-58;         ^^^^^^^^^^^^ 我也搞不懂如果這裡不減掉檔頭播放時會出現個爆音          ,還等高手幫忙解惑^^"   for i:=0 to wav1.Size do begin   bBuf:=i;   wav1.Position:=i;   wav1.Read(bBuf,1);   buffer[i]:=bBuf;  end; wav1.Clear; Wav1.LoadFromFile('c:\program files\cmmsvc\voice\202.wav');  for i:=58 to wav1.Size do begin   bBuf:=i;   wav1.Position:=i;   wav1.Read(bBuf,1);   buffer[wavlen-1+i]:=bBuf;  end; wavlen:=wavlen+wav1.Size-58; countlen:=wavlen-58; 備註一下小的用的是8k8bit CCITT u-law的檔頭所以大大如果要用其他的格式 可能得翻一下其他檔頭的資料下面的動作旨在重新寫入資料長度 buffer[46]:=countlen mod 256; buffer[47]:=(countlen Div 256) mod 256; buffer[48]:=(countlen Div (256*256)mod 256); buffer[49]:=countlen DiV (256*256*256); buffer[54]:=buffer[46]; buffer[55]:=buffer[47]; buffer[56]:=buffer[48]; buffer[57]:=buffer[49]; wav1.Clear; wav1.WriteBuffer(buffer,wavlen+58);                               ^^^ 加回第一次載入被砍掉的58Byte 這樣作                               就不會出現爆音 怪怪的吶^^" // > 發表人 -
mine
中階會員


發表:28
回覆:129
積分:56
註冊:2004-03-31

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-05-26 16:20:46 IP:61.221.xxx.xxx 未訂閱
順便請教各位高手 檔頭58byte的CCITT u-law格式經過Mediaplay.save 轉存後檔頭變成了46byte 有法子維持原本的檔頭嗎 還是一定得再去修一次?? 主要是chunkdata的資料被吞了 不過播放上還可以播的出來 但是如果要再跟其他的ulaw 格式合併 得先注意檔頭了 所以用mediaplay叫出來修改的大大可能得留心一下 不然檔案會能合併但是後來加入的聲音檔出不來 正在想放棄mediaplay中~"~ ----------------------------------------- 搞不懂!搞不懂!永遠都搞不懂!
dsp
一般會員


發表:14
回覆:23
積分:7
註冊:2003-10-14

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-05-28 08:41:04 IP:218.171.xxx.xxx 未訂閱
上面大大好 請問大大你 wavlen:=wavlen wav1.Size-58; countlen:=wavlen-58;<<<<<<<為什麼還要-58呢?因為兩個檔頭部分不是已經減調了嗎? 另外wav1.WriteBuffer(buffer,wavlen 58);這行是把檔頭58存回去嗎? 可是我這行我就不會改成bcb個格式可否教我怎改嗎? 謝謝大大
mine
中階會員


發表:28
回覆:129
積分:56
註冊:2004-03-31

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-05-28 14:21:00 IP:61.221.xxx.xxx 未訂閱
我把原本的程式整理了一下你再看一次 會減二次58是因為buffer[wavlen-58 i]:=bBuf;並不是接著上一個檔的結尾續寫的而是往前覆蓋了58byte 至於為什麼這麼作因為減一個小於58的數結合檔的中間會有一個爆音(原因不明這是我來請教的地方)大於58則不會有這樣的情形但避免砍掉上一個檔太多所以能消掉爆音的最小值所以第一次取到的wavlen其是包含檔頭的大小但由於是從buffer[wavlen-58 i]:=bBuf被寫入所以第一次檔案的大小其實已經縮小了58byte第二次的wav1.size因為只取資料不含檔頭所以再減了一次58Byte結果就是wavlen:=wavlen-58 wav1.Size-58;現在的wavlen是有含(檔頭大小的)data的資料長度是等於檔案大小(wavlen)減掉檔頭(58Byte)所以要寫入fact跟data的值就是wavlen-58=countlen,當然如果你不在意結合後會有爆音的產生是只要減一次58byte寫入的地方也就從buffer[wavlen i]:=bBuf上次結尾的地方寫入就行了 至於BCB 我並沒有BCB的程式不曉得他有沒有 WAV1-->WriteBuffer(char *buffer,int wavlen);的用法 還是請BCB的高手幫忙解答吧^^" -------------------------------------------------- 搞不懂!搞不懂!永遠都搞不懂!
dsp
一般會員


發表:14
回覆:23
積分:7
註冊:2003-10-14

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-05-29 00:18:45 IP:218.171.xxx.xxx 未訂閱
上面大大你好 謝謝你-58的問題我了解了 請問你wav1.WriteBuffer(buffer,wavlen 58);這行 是不是把新的檔頭 第一個去檔部分 第二個去檔部分 重新寫入那裡呢?是bBuf的記憶體部分還是那呢? 像 for i:=58 to wav1.Size do begin bBuf:=i; wav1.Position:=i; wav1.Read(bBuf,1); buffer[wavlen-58 i]:=bBuf; 我會 但要把陣列寫回去bBuf 有一行程式是寫回去的如下 wav1.Write(bBuf,1); 謝謝大大
mine
中階會員


發表:28
回覆:129
積分:56
註冊:2004-03-31

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-05-30 23:56:27 IP:218.175.xxx.xxx 未訂閱
引言: 請問你wav1.WriteBuffer(buffer,wavlen 58);這行 我已經改寫了原有的程式你再看一下=,在delphi裡的定義 TmemoryStream.writeBuffer(const buffer,count integer); 是把一個buffer寫進stream的buffer裡,或許變數定義成buffer讓你搞混了如果陣列是定義成kk:array[0..$FFFFFF] of Byte 那寫回去就是用 writebuffer(kk,寫入的大小);讓stream的buffer完全覆寫成kk 但要把陣列寫回去bBuf 有一行程式是寫回去的如下 wav1.Write(bBuf,1); 如果用wirte可以指定自wav1的buffer自你指定的position插入你指定的buffer資料跟大小也就是說如果你自別的buffer要從別的object插入資料是可以用write的上面的程式可以改寫 在bcb 你試試這裡的寫法 write的用法 wav1->clear; wav1->position:=0; wav1->wirte (&buffer,sizeof(wavlen)); writebuffer的用法 wav1->WriteBuffer( &buffer, sizeof(wavlen) ); 站上有很多高手的文章你可以多看看,畢竟我也還在學 還有疑問你可以多參考taishyang 大大的文章
--------------------------------- 搞不懂!搞不懂!學不完所以永遠都搞不懂
mine
中階會員


發表:28
回覆:129
積分:56
註冊:2004-03-31

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-06-03 11:12:27 IP:61.221.xxx.xxx 未訂閱
找到資料了 而且這程式有個小小的bug 我忽略了 RIFF的檔頭資料跟內容所以引用的大大要再注意一下以下是有關fact chunk的資料給大家作個參考 FACT Chunk The  fact chunk stores important information about the contents of the WAVE file. This chunk is defined as follows: -> fact( ) // Number of samples The `fact'' chunk is required if the waveform data is contained in a `wavl'' LIST chunk and for all compressed audio formats. The chunk is not required for PCM files using the `data'' chunk format. The "fact" chunk will be expanded to include any other information required by future WAVE formats. Added fields will appear following the field. Applications can use the chunk size field to determine which fields are present. Cue-Points Chunk The cue-points chunk identifies a series of positions in the waveform data stream. The is defined as follows: -> cue( // Count of cue points ... ) // Cue-point table -> struct { DWORD dwName; DWORD dwPosition; FOURCC fccChunk; DWORD dwChunkStart; DWORD dwBlockStart; DWORD dwSampleOffset; } The fields are as follows: Field Description dwName Specifies the cue point name. Each record must have a unique dwName field. dwPosition Specifies the sample position of the cue point.This is the sequential sample number within the play order. See ``Playlist Chunk,'' later in this document, for a discussion of the play order. fccChunk Specifies the name or chunk ID of thechunk containing the cue point. dwChunkStart Specifies the file position of the start of the chunk containing the cue point. This is a byte offset relative to the start of the data section of the `wavl' LIST chunk. dwBlockStart Specifies the file position of the start of the block containing the position. This is a byte offset relative to the start of the data section of the `wavl' LIST chunk. dwSampleOffset Specifies the sample offset of the cuepoint relative to the start of the block. 爆音的產生跟 檔頭有誤有闗係 就此結案了 謝謝有幫忙動過腦的大大 ------------------------------------------------------------- 搞不懂!搞不懂!!永遠都搞不懂!!
系統時間:2024-05-06 8:58:39
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!