求助:如何把两段WAV格式音频合成一个

求助:如何把两段WAV格式音频合成一个,第1张

将两段WAV音频合并成一个音频文件,你可以使用

超级转基弊毕换秀

软件的“音频转换通”选项卡支持将两段WAV音频合并在一起,合并搏芹的音频质量非常清晰。

速度是评测中最快的,支持更多的CPU优化,并将音频保存为MP3、WMA、WAV、AAC、APE等格式。

百度卜碰搜索

超级转换秀

#include <stdio.h>

#include <string.h>

#define RIFF_SIGN_ID 0x46464952ul

#define WAVE_SIGN_ID 0x45564157ul

#define FMT__SIGN_ID 0x20746D66ul

#define FACT_SIGN_ID 谨州0x74636166ul

#define DATA_SIGN_ID 0x61746164ul

#ifndef DWORD 

typedef unsigned long  DWORD

#endif

#ifndef WORD 

typedef unsigned short WORD

#endif

#ifndef BYTE

typedef unsigned char  BYTE

#endif

struct RIFF_HEADER

{

DWORD RiffID     // 资源交换文件标志 0x46464952 'R','I','F','F'

DWORD RiffSize   // 从下个地址开始到文件尾的总字节

DWORD RiffFormat // WAV文件标志 0x45564157 'W','A','V','E'

}

struct WAVE_FORMAT

{

WORD  FormatTag      // 格式种类(值为1时,表示数据为线性PCM编码)

WORD  Channels       // 通道数,单声道为1,双声道为2

DWORD SamplesPerSec  // 采样频率

DWORD AvgBytesPerSec // 每秒所需字节数 

WORD  BlockAlign     // 数据块对齐单位(每个采样需要的字节数)

WORD  BitsPerSample  // 每个采样需要的bit数 

WORD  otherInfo      // 附加信息(可选,通过Size来判断有无)

}

struct FMT_BLOCK

{

DWORD       FmtID     // 波形格式标志 0x20746D66 'f','m','t',' '

DWORD       FmtSize   // 波形格式部分长度贺晌乎(一般为00000010H)

WAVE_FORMAT wavFormat // 波形数据格式

}

struct UNKNOW_BLOCK

{

DWORD ID   // 未知块

DWORD Size // 未知块长度

}

struct FACT_BLOCK

{

DWORD FactID   // 可选部分标识 0x74636166 'f','a','c','t'

DWORD FactSize // 可选部分长度

BYTE  Data[1]  // 可选部分数据

}

struct DATA_BLOCK

{

DWORD DataID   // 数据标志符 0x61746164, 'd','a','t','a'

DWORD DataSize // DATA总数据长度字节

BYTE  Data[1]  // 数据

}

BYTE * openWaveFile(const char *name)

BYTE * getWaveData(BYTE * wav, int * dLen)

void   printWaveFormat(BYTE * wav)

int    saveWaveFile(const char * name, BYTE * wav)

BYTE 禅悉* catWave(BYTE *& wav1, BYTE *& wav2)

size_t getTotalLen(BYTE * wav)

int main(int argc, char* argv[])

{

int dLen

BYTE * data1 = openWaveFile("1.wav")

printWaveFormat(data1)

BYTE * data2 = openWaveFile("2.wav")

printWaveFormat(data2)

data1 = catWave(data1, data2)

printWaveFormat(data1)

saveWaveFile("3.wav", data1)

return 0

}

BYTE * openWaveFile(const char *name)

{

size_t readByte

FILE * fp = fopen(name, "rb")

if(fp==NULL) return NULL

RIFF_HEADER fh

if(fread(&fh, sizeof(fh), 1, fp) != 1)

{

fclose(fp)

printf("Riff Header 文件长度错误\n")

return NULL

}

if(fh.RiffFormat != WAVE_SIGN_ID || fh.RiffID != RIFF_SIGN_ID)

{

fclose(fp)

printf("文件标识符错误 ID:%08X Format:%08X\n", fh.RiffID, fh.RiffFormat)

return NULL

}

BYTE * r = new BYTE[fh.RiffSize + 10], *pr

if(r==NULL)

{

fclose(fp)

printf("内存申请错误\n")

return NULL

}

readByte = fread(r, 1, fh.RiffSize-4, fp)

if(readByte != fh.RiffSize-4)

{

delete [] r

printf("wave 文件长度错误 %d %d\n", readByte, fh.RiffSize)

return NULL

}

fclose(fp)

FMT_BLOCK *fb = (FMT_BLOCK *)r

if(fb->FmtID != FMT__SIGN_ID)

{

printf("格式标识符错误或格式大小错误ID:%08X\n", fb->FmtID)

delete [] r

return NULL

}

if(fb->wavFormat.FormatTag != 1)

{

delete [] r

printf("不支持的格式 Format:%d\n", fb->wavFormat.FormatTag)

return NULL

}

pr = r + 8 + fb->FmtSize

while(1)

{

UNKNOW_BLOCK * ub = (UNKNOW_BLOCK *)pr

if(ub->ID == FACT_SIGN_ID)

{

printf("Fact 标签 length: %d\n", ub->Size)

pr += 8 + ub->Size 

}

else break

}

DATA_BLOCK * db = (DATA_BLOCK *)pr

if(db->DataID  != DATA_SIGN_ID)

{

delete [] r

printf("数据错误\n")

return NULL

}

return r

}

BYTE * getWaveData(BYTE * wav, int * dLen)

{

UNKNOW_BLOCK * ub = (UNKNOW_BLOCK *)wav

while(ub->ID != DATA_SIGN_ID)

{

switch(ub->ID)

{

case DATA_SIGN_ID:

break

case FMT__SIGN_ID:

case FACT_SIGN_ID:

ub = (UNKNOW_BLOCK *)(((BYTE *)ub) + ub->Size + 8)

break

default:

printf("错误标签 %08X\n", ub->ID )

return NULL

}

}

DATA_BLOCK * db = (DATA_BLOCK *)ub

*dLen = db->DataSize

return db->Data

}

size_t getTotalLen(BYTE * wav)

{

size_t r = 0

UNKNOW_BLOCK * ub = (UNKNOW_BLOCK *)wav

while(1)

{

switch(ub->ID)

{

case DATA_SIGN_ID:

r += ub->Size + 8

return r

case FMT__SIGN_ID:

case FACT_SIGN_ID:

r += ub->Size + 8

ub = (UNKNOW_BLOCK *)(((BYTE *)ub) + ub->Size + 8)

break

default:

printf("错误标签 %08X\n", ub->ID )

return NULL

}

}

return -1

}

void printWaveFormat(BYTE * wav)

{

int len

getWaveData(wav, &len)

FMT_BLOCK *fb = (FMT_BLOCK *)wav

printf("Wave 格式:PCM\n")

printf("通道数量:%d\n", fb->wavFormat.Channels )

printf("采样频率:%dHz\n", fb->wavFormat.SamplesPerSec )

printf("每秒所需字节数:%d字节\n", fb->wavFormat.AvgBytesPerSec )

printf("数据块对齐单位:%d字节\n", fb->wavFormat.BlockAlign )

printf("每个采样需要的bit数:%dbit\n", fb->wavFormat.BitsPerSample )

printf("长度:%.2f 秒\n", (double)len / fb->wavFormat.AvgBytesPerSec)

}

BYTE * catWave(BYTE *& wav1, BYTE *& wav2)

{

FMT_BLOCK * fb1 = (FMT_BLOCK *)wav2

const FMT_BLOCK * fb2 = (const FMT_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)

{

int len1 = getTotalLen(wav1), len2

BYTE * Data2 = getWaveData(wav2, &len2)

BYTE * nD = new BYTE[len1 + len2 + 10]

if(nD == NULL) return NULL

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)

return wav1

}

return NULL

}

int saveWaveFile(const char * name, BYTE * wav)

{

FILE *fp = fopen(name, "wb")

if(fp == 0) return 0

int len = getTotalLen(wav)

RIFF_HEADER rh

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)

return 1

}

这不是三言两语的事情,合作wav文件 *** 作并不简单。要研究好wav文件结构,读取文件头,再进行分析和 *** 作。

有两种办法:

1.连续播放,例如:

#include <stdio.h>

#include <windows.h>

#include <mmsystem.h>神唤

#pragma comment(lib, "winmm.lib")

int main(){

    PlaySound("C:\\Users\\wang\\test1.wav", NULL, SND_FILENAME)

    PlaySound("C:\\Users\\wang\\test2.wav", NULL, SND_FILENAME)

    PlaySound("C:\\Users\\wang\\test3.wav", NULL, SND_FILENAME)

    return 0

}

2.系统自带的“windows movie maker”槐瞎答。运行windows movie maker,然后选择“导入音频或音乐”之后把你需要的文件添加进来。然后按照你自己需要排列的顺序把这些文件依次拖到下铅慧方的时间线上。然后点左上方的“文件”选项,最后保存电影文件即可。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/tougao/8225434.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存