當前位置:首頁 » 編程語言 » 怎樣用c語言合並ms4音頻
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

怎樣用c語言合並ms4音頻

發布時間: 2022-04-27 07:44:07

c語言編寫程序將多個wav文件拼接成一個音頻wav文件並播放

#include<stdio.h>
#include<string.h>

#defineRIFF_SIGN_ID0x46464952ul
#defineWAVE_SIGN_ID0x45564157ul
#defineFMT__SIGN_ID0x20746D66ul
#defineFACT_SIGN_ID0x74636166ul
#defineDATA_SIGN_ID0x61746164ul

#ifndefDWORD
typedefunsignedlongDWORD;
#endif

#ifndefWORD
typedefunsignedshortWORD;
#endif

#ifndefBYTE
typedefunsignedcharBYTE;
#endif
structRIFF_HEADER
{
DWORDRiffID;//資源交換文件標志0x46464952'R','I','F','F'
DWORDRiffSize;//從下個地址開始到文件尾的總位元組數
DWORDRiffFormat;//WAV文件標志0x45564157'W','A','V','E'
};

structWAVE_FORMAT
{
WORDFormatTag;//格式種類(值為1時,表示數據為線性PCM編碼)
WORDChannels;//通道數,單聲道為1,雙聲道為2
DWORDSamplesPerSec;//采樣頻率
DWORDAvgBytesPerSec;//每秒所需位元組數
WORDBlockAlign;//數據塊對齊單位(每個采樣需要的位元組數)
WORDBitsPerSample;//每個采樣需要的bit數
WORDotherInfo;//附加信息(可選,通過Size來判斷有無)
};

structFMT_BLOCK
{
DWORDFmtID;//波形格式標志0x20746D66'f','m','t',''
DWORDFmtSize;//波形格式部分長度(一般為00000010H)
WAVE_FORMATwavFormat;//波形數據格式
};

structUNKNOW_BLOCK
{
DWORDID;//未知塊
DWORDSize;//未知塊長度
};

structFACT_BLOCK
{
DWORDFactID;//可選部分標識0x74636166'f','a','c','t'
DWORDFactSize;//可選部分長度
BYTEData[1];//可選部分數據
};

structDATA_BLOCK
{
DWORDDataID;//數據標志符0x61746164,'d','a','t','a'
DWORDDataSize;//DATA總數據長度位元組
BYTEData[1];//數據
};


BYTE*openWaveFile(constchar*name);
BYTE*getWaveData(BYTE*wav,int*dLen);
voidprintWaveFormat(BYTE*wav);
intsaveWaveFile(constchar*name,BYTE*wav);
BYTE*catWave(BYTE*&wav1,BYTE*&wav2);
size_tgetTotalLen(BYTE*wav);

intmain(intargc,char*argv[])
{
intdLen;
BYTE*data1=openWaveFile("1.wav");
printWaveFormat(data1);
BYTE*data2=openWaveFile("2.wav");
printWaveFormat(data2);
data1=catWave(data1,data2);
printWaveFormat(data1);
saveWaveFile("3.wav",data1);
return0;
}

BYTE*openWaveFile(constchar*name)
{
size_treadByte;
FILE*fp=fopen(name,"rb");
if(fp==NULL)returnNULL;

RIFF_HEADERfh;
if(fread(&fh,sizeof(fh),1,fp)!=1)
{
fclose(fp);
printf("RiffHeader文件長度錯誤 ");
returnNULL;
}
if(fh.RiffFormat!=WAVE_SIGN_ID||fh.RiffID!=RIFF_SIGN_ID)
{
fclose(fp);
printf("文件標識符錯誤ID:%08XFormat:%08X ",fh.RiffID,fh.RiffFormat);
returnNULL;
}
BYTE*r=newBYTE[fh.RiffSize+10],*pr;
if(r==NULL)
{
fclose(fp);
printf("內存申請錯誤 ");
returnNULL;
}
readByte=fread(r,1,fh.RiffSize-4,fp);
if(readByte!=fh.RiffSize-4)
{
delete[]r;
printf("wave文件長度錯誤%d%d ",readByte,fh.RiffSize);
returnNULL;
}
fclose(fp);

FMT_BLOCK*fb=(FMT_BLOCK*)r;
if(fb->FmtID!=FMT__SIGN_ID)
{
printf("格式標識符錯誤或格式大小錯誤ID:%08X ",fb->FmtID);
delete[]r;
returnNULL;
}
if(fb->wavFormat.FormatTag!=1)
{
delete[]r;
printf("不支持的格式Format:%d ",fb->wavFormat.FormatTag);
returnNULL;
}

pr=r+8+fb->FmtSize;
while(1)
{
UNKNOW_BLOCK*ub=(UNKNOW_BLOCK*)pr;
if(ub->ID==FACT_SIGN_ID)
{
printf("Fact標簽length:%d ",ub->Size);
pr+=8+ub->Size;
}
elsebreak;
}
DATA_BLOCK*db=(DATA_BLOCK*)pr;
if(db->DataID!=DATA_SIGN_ID)
{
delete[]r;
printf("數據錯誤 ");
returnNULL;
}
returnr;
}

BYTE*getWaveData(BYTE*wav,int*dLen)
{
UNKNOW_BLOCK*ub=(UNKNOW_BLOCK*)wav;
while(ub->ID!=DATA_SIGN_ID)
{
switch(ub->ID)
{
caseDATA_SIGN_ID:
break;
caseFMT__SIGN_ID:
caseFACT_SIGN_ID:
ub=(UNKNOW_BLOCK*)(((BYTE*)ub)+ub->Size+8);
break;
default:
printf("錯誤標簽%08X ",ub->ID);
returnNULL;
}
}
DATA_BLOCK*db=(DATA_BLOCK*)ub;
*dLen=db->DataSize;
returndb->Data;
}

size_tgetTotalLen(BYTE*wav)
{
size_tr=0;
UNKNOW_BLOCK*ub=(UNKNOW_BLOCK*)wav;
while(1)
{
switch(ub->ID)
{
caseDATA_SIGN_ID:
r+=ub->Size+8;
returnr;
caseFMT__SIGN_ID:
caseFACT_SIGN_ID:
r+=ub->Size+8;
ub=(UNKNOW_BLOCK*)(((BYTE*)ub)+ub->Size+8);
break;
default:
printf("錯誤標簽%08X ",ub->ID);
returnNULL;
}
}
return-1;
}
voidprintWaveFormat(BYTE*wav)
{
intlen;
getWaveData(wav,&len);
FMT_BLOCK*fb=(FMT_BLOCK*)wav;
printf("Wave格式:PCM ");
printf("通道數量:%d ",fb->wavFormat.Channels);
printf("采樣頻率:%dHz ",fb->wavFormat.SamplesPerSec);
printf("每秒所需位元組數:%d位元組 ",fb->wavFormat.AvgBytesPerSec);
printf("數據塊對齊單位:%d位元組 ",fb->wavFormat.BlockAlign);
printf("每個采樣需要的bit數:%dbit ",fb->wavFormat.BitsPerSample);
printf("長度:%.2f秒 ",(double)len/fb->wavFormat.AvgBytesPerSec);
}

BYTE*catWave(BYTE*&wav1,BYTE*&wav2)
{
FMT_BLOCK*fb1=(FMT_BLOCK*)wav2;
constFMT_BLOCK*fb2=(constFMT_BLOCK*)wav2;
if(
fb1->wavFormat.AvgBytesPerSec==fb2->wavFormat.AvgBytesPerSec&&
fb1->wavFormat.BitsPerSample==fb2->wavFormat.BitsPerSample&&
fb1->wavFormat.BlockAlign==fb2->wavFormat.BlockAlign&&
fb1->wavFormat.Channels==fb2->wavFormat.Channels&&
fb1->wavFormat.FormatTag==fb2->wavFormat.FormatTag&&
fb1->wavFormat.SamplesPerSec==fb2->wavFormat.SamplesPerSec)
{
intlen1=getTotalLen(wav1),len2;
BYTE*Data2=getWaveData(wav2,&len2);
BYTE*nD=newBYTE[len1+len2+10];
if(nD==NULL)returnNULL;
memcpy(nD,wav1,len1);
delete[]wav1;
wav1=nD;
BYTE*Data1=getWaveData(wav1,&len1);
DATA_BLOCK*db1=(DATA_BLOCK*)(Data1-8);
db1->DataSize+=len2;
memcpy(Data1+len1,Data2,len2);
returnwav1;
}
returnNULL;
}

intsaveWaveFile(constchar*name,BYTE*wav)
{
FILE*fp=fopen(name,"wb");
if(fp==0)return0;
intlen=getTotalLen(wav);
RIFF_HEADERrh;
rh.RiffFormat=WAVE_SIGN_ID;
rh.RiffID=RIFF_SIGN_ID;
rh.RiffSize=len+4;
fwrite(&rh,sizeof(rh),1,fp);
fwrite(wav,1,len,fp);
fclose(fp);
return1;
}

② 如何用c語言編輯音樂

無法使用c語言編輯音樂
編輯音樂的都是匯編之類的低級語言
高級語言沒有和音樂有關的指令
[其中VB能播放音樂完全是因為用了匯編做出來的控制項起的作用]

③ C語言如何將多個.mp3文件合並到一個.bin文件裡面呀求代碼

最簡單的就是用cmd下的命令行,比如 /b 1.mp3+2.mp3 3.mp3就可以將1和2合並成3,你直接生成這個字元串,執行就行了。

④ C語言文件合並

文件的合並要使用到FILE類型,以及文件的打開關閉,下面以圖片文件和其它類型的文件進行合並為例,說說文件的合並:

#include<stdio.h>
#include<stdlib.h>
voidmain()
{
FILE*fp,*ff,*ftt;
charch;
charfn1[20],fn2[20],ft[20];
printf(" 圖片文件合成器 ");
printf("輸入要合成的圖片名稱:");
scanf("%s",fn1);
printf("輸入要合成的文件名稱:");
scanf("%s",fn2);
printf("生成的名稱:");
scanf("%s",ft);
if(!(fp=fopen(fn1,"rb")))//當不能打開圖片文件的提示處理
{
printf("不能打開圖片%s ",fn1);
return;
}
if(!(ff=fopen(fn2,"rb")))
{
printf("不能打開文件%s",fn2);
return;
}
if(!(ftt=fopen(ft,"wb")))
{
printf("不能打開%s",ft);
return;
}

while(!(feof(fp)))//寫入圖片文件
{
ch=fgetc(fp);
fputc(ch,ftt);
}
fclose(fp);


while(!(feof(ff)))//寫入其它類型的文件
{
ch=fgetc(ff);
fputc(ch,ftt);
}
fclose(ff);
fclose(ftt);
system("pause");

}

要注意了,這個例子涉及的文件均要在cpp文件的同一級目錄,要是不在同一級目錄則要輸入文件的路徑,合成的文件也在cpp文件的目錄下。