wav檔的合併存檔播放 |
缺席
|
mine
中階會員 發表:28 回覆:129 積分:56 註冊:2004-03-31 發送簡訊給我 |
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 發送簡訊給我 |
順便請教各位高手 檔頭58byte的CCITT u-law格式經過Mediaplay.save 轉存後檔頭變成了46byte 有法子維持原本的檔頭嗎 還是一定得再去修一次??
主要是chunkdata的資料被吞了 不過播放上還可以播的出來 但是如果要再跟其他的ulaw 格式合併 得先注意檔頭了 所以用mediaplay叫出來修改的大大可能得留心一下 不然檔案會能合併但是後來加入的聲音檔出不來 正在想放棄mediaplay中~"~ -----------------------------------------
搞不懂!搞不懂!永遠都搞不懂!
|
dsp
一般會員 發表:14 回覆:23 積分:7 註冊:2003-10-14 發送簡訊給我 |
|
mine
中階會員 發表:28 回覆:129 積分:56 註冊:2004-03-31 發送簡訊給我 |
我把原本的程式整理了一下你再看一次
會減二次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 發送簡訊給我 |
上面大大你好
謝謝你-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 發送簡訊給我 |
引言: 請問你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 發送簡訊給我 |
找到資料了 而且這程式有個小小的bug 我忽略了 RIFF的檔頭資料跟內容所以引用的大大要再注意一下以下是有關fact chunk的資料給大家作個參考
FACT Chunk
The
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |