请问如何将多个wav文件合成一个wav文件

lxm75 2003-03-21 01:43:13
我用MS-DOS下的Copy/b file1.wav+file2.wav file3.wav命令和自己编代码(将file1.wav、file2.wav的4H<文件大小>、40H<声音大小>处的long int分别相加并分别写入file3.wav相应位置)拷贝结果都是file3.wav大小等于file1.wav+file2.wav,但是声音却只有file1.wav的声音,请问这到底是怎么回事?我应该怎么解决?
...全文
294 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
阿鹏兄 2003-03-26
  • 打赏
  • 举报
回复
用专门的合并工具?
lxm75 2003-03-25
  • 打赏
  • 举报
回复
我给大家的分呢?
lxm75 2003-03-25
  • 打赏
  • 举报
回复
哥哥们,成功了,太高兴了。
请kataboy(小浩子)、copy_paste(木石三)兄弟再到如下帖子领分
http://expert.csdn.net/Expert/topic/1482/1482357.xml?temp=.6055567
lxm75 2003-03-25
  • 打赏
  • 举报
回复
哥们们先谢谢了,我先试试看。
  • 打赏
  • 举报
回复
DOS 的COPY 命令加上个参数就能完成, 以前经常用来合并电影文件
copy_paste 2003-03-25
  • 打赏
  • 举报
回复
哦,晕,白打了,楼上的还详细。。。
copy_paste 2003-03-25
  • 打赏
  • 举报
回复
一个wave文件格式:

1- 4字节:'RIFF'
5- 8字节:int
9-12字节:'WAVE'

13-16字节:'fmt '(有个空格)
17-20字节:int (保存了18个字节的WAVEFORMATEX格式的内存)
21-38字节:WAVEFORMATEX 结构的内存

39-42字节:'fact'
43-46字节:int(一般是=4,即下一个Chunk需要跳过4个字节)
47-50字节:(可能是保留)

51-54字节:'data'
55-58字节: int (保存Wave文件中Data的长度)

所以可以定义两个结构体就可以读它了。

typedef struct
{
int FType;
int Size;
int RType;
}TWaveFileHeader;

typedef strcut
{
int CType;
int Size;
}TWaveChunkHeader;

两个Wave文件的音频格式相不相同,看文件中WaveFormatEx的各项值相不相同就行了。然后修改data的后面的size就完了。
sprewellkobe 2003-03-25
  • 打赏
  • 举报
回复
GZ
kataboy 2003-03-25
  • 打赏
  • 举报
回复

你首先要知道音频裸数据的长度, 也就是 buffer 的 size 。
看下面的结构,一开始有 八个字节是一个结构, 第一个 四字节 是标志,刚好等于 ascii 的 "RIFF" ,第二个四字节是总的文件长度减去8。你可以验证一下。(参照16进制阅读数字的方法)
跟着是第二个数据结构,占12个字节,如果你是标准的 wave 格式的文件,那么就是紧接着两个标志,第一个四字节的标志是 ascii 的 "WAVE" ,第二个 四字节的标志就是 ascii 的 "fmt "(注意,有一个空格),然后剩下的四字节里面藏的是 WAVEFORMATEX 结构的大小(参照MSDN),应该是18个字节。
然后,当然就是 18个字节的 WAVEFORMATEX 结构里面的值。详细的就不说了,自己查一下 MSDN。
在这 18 个字节后面 (按照旧时候的方法),应该是跟着一个8字节的结构的,然后就是 "裸数据" 的开始地址了,这八字节结构的开始四字节是标志,应该等于 ascii 的 "data",然后紧跟着的四字节就是裸数据的大小了,也就是最重要的部分。
好了,如此一来,你就可以得到音频裸数据的起始位置(紧紧跟在含"data"标志的数据结构的后面),还有就是音频数据的长度了。应该是所有的问题都很容易解决的。

不过,还要注意,就是现在的很多 .wav 文件都会外加一个数据结构(12字节),就加在 WAVEFORMATEX 的后面和 含 "data" 的数据结构前面。 这个外加的结构 第一个四字节是标志,等于 ascii 码的 "fact",然后第二个四字节的值在大部分情况下都等于 4, 第三个四字节的值也是等于 音频裸数据的长度。 基本上就是这样了。
如果你希望追加另外一个音频数据到第一个 wave 文件上,当然,一开头的结构中的总长度要加上,然后,裸数据的长度也要加为总和,之后就是将第二个 wave 的裸数据追加到第一个 wave 文件的裸数据后面了。
kataboy 2003-03-25
  • 打赏
  • 举报
回复
很简单的,我要组织一下
lxm75 2003-03-25
  • 打赏
  • 举报
回复
kataboy(小浩子) 朋友:
是一样的,都是8k,16bit,单声道

laishishenghust(赤脚狂奔) 朋友:
file1文件尾去掉也已经实验过,不知道你是不是,去掉后成功了?反正我是没有成功,你知道是什么原因吗?
laishishenghust 2003-03-25
  • 打赏
  • 举报
回复
file1文件的尾也要去掉
kataboy 2003-03-25
  • 打赏
  • 举报
回复
你两个WAV的取样频率是一样的吗?
lxm75 2003-03-25
  • 打赏
  • 举报
回复
有好心的朋友帮我这个忙吗?
lxm75 2003-03-24
  • 打赏
  • 举报
回复
兄弟们,帮帮忙吧,我该怎么做?
lxm75 2003-03-23
  • 打赏
  • 举报
回复
哥哥们,我不但把它们头给剪了,连尾巴都剪了一截,可是没有用呀,帮忙看看吧!
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Copy_Main.h"
#include <io.h>
#include <fcntl.h>

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
int fp1,fp2,fp3;
long int file_len,len;
long int file_len1,len1;
long int file_len2,len2;
long int len3,file_len3;
char byte_buf;
char byte_buf2;
char byte_buf3[4];
String str1,str2,str3;


str1="e:\\1.wav";
str2="e:\\2.wav";
str3="e:\\3.wav";
fp1=open(str1.c_str(),O_RDONLY|O_BINARY);
fp2=open(str2.c_str(),O_RDONLY|O_BINARY);
fp3=open(str3.c_str(),O_CREAT|O_RDWR|O_BINARY);

lseek(fp1,4,SEEK_SET);
read(fp1,&len3,sizeof(len3));
file_len1=len3;
lseek(fp1,40,SEEK_SET);
read(fp1,&len3,sizeof(len3));
len1=len3;

lseek(fp2,4,SEEK_SET);
read(fp2,&len3,sizeof(len3));
file_len2=len3;
lseek(fp2,40,SEEK_SET);
read(fp2,&len3,sizeof(len3));
len2=len3;


file_len=filelength(fp1);
len=0;
while(len<file_len)
{
lseek(fp1,len,SEEK_SET);
read(fp1,&byte_buf,1);
lseek(fp3,0,SEEK_END);
write(fp3,&byte_buf,1);
len++;
}

file_len=filelength(fp2);
len=0;
while(len<file_len-44)
{
lseek(fp2,len+44,SEEK_SET);
read(fp2,&byte_buf2,1);
lseek(fp3,0,SEEK_END);
write(fp3,&byte_buf2,1);
len++;
}
/*
len3=len1+len2;
//file_len3=filelength(fp1)+filelength(fp2)-44;
file_len3=file_len1+file_len2-44;
lseek(fp3,4,SEEK_SET);
write(fp3,&file_len3,sizeof(file_len3));
lseek(fp3,40,SEEK_SET);
write(fp3,&len3,sizeof(len3));
*/
close(fp1);
close(fp2);
close(fp3);
}
//---------------------------------------------------------------------------
pp616 2003-03-21
  • 打赏
  • 举报
回复
呵呵。楼上说的对。把头剪了。后面的数据堆上去就ok了。
kingfish 2003-03-21
  • 打赏
  • 举报
回复
1.把File2的头(44)去掉
2.把File2的数据接在File1后面,修改File1数据长度(File1数据长度+File2数据长度)
lxm75 2003-03-21
  • 打赏
  • 举报
回复
我的E-Mail:LXM@juwei.net

13,824

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧