开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 1502|回复: 2
收起左侧

[已解决] 求助 C语言 原 翻译成 易语言 谁有wav合并也可以

 关闭 [复制链接]
结帖率:100% (3/3)
发表于 2017-3-31 19:56:39 | 显示全部楼层 |阅读模式   江西省赣州市
200精币
#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;
}

最佳答案

查看完整内容

兄弟,不用那么麻烦,弄一个ffmpeg 来利用命令行来合并wav效果都比你发来的那个要好!~ 自行百度一下ffmpeg ,很多播放器和转码软件都是依赖ffmpeg来进行解码和转换的 补充内容 (2017-3-31 20:08): http://www.cnblogs.com/hdu-2010/p/5791097.html 《用ffmpeg合并音频文件》

回答提醒:如果本帖被关闭无法回复,您有更好的答案帮助楼主解决,请发表至 源码区 可获得加分喔。
友情提醒:本版被采纳的主题可在 申请荣誉值 页面申请荣誉值,获得 1点 荣誉值,荣誉值可兑换荣誉会员、终身vip用户组。
快捷通道:申请荣誉值无答案申请取消悬赏投诉有答案未采纳为最佳

结帖率:100% (2/2)
发表于 2017-3-31 19:56:40 | 显示全部楼层   内蒙古自治区兴安盟
兄弟,不用那么麻烦,弄一个ffmpeg 来利用命令行来合并wav效果都比你发来的那个要好!~ 自行百度一下ffmpeg ,很多播放器和转码软件都是依赖ffmpeg来进行解码和转换的

补充内容 (2017-3-31 20:08):
http://www.cnblogs.com/hdu-2010/p/5791097.html
《用ffmpeg合并音频文件》

评分

参与人数 1荣誉 +1 收起 理由
笨潴 + 1 热心帮助他人,荣誉+1,希望继续努力(*^__^*) 嘻嘻!

查看全部评分

回复

使用道具 举报

结帖率:96% (24/25)
发表于 2017-3-31 20:07:31 | 显示全部楼层   广东省深圳市
翻译啥啊,直接做成模块调用就好了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表