c/c++语言产生正弦波音频数据代码

/*
 * author: hjjdebug
 * date  : 2023年 12月 12日 星期二 14:33:22 CST
 * descritor: 怎样产生正弦波音频数据
 */

#include <stdio.h>
#include <math.h>
/*
 * 产生1s 440hz, S16格式的音频数据,48K hz 采样,单声道,每个frame大小为1024
 * 这就是数字声音的概念. 采样的数据格式,采样率(每秒采样次数),声道数,frame大小
 * 你可以用如下命令播放生成的声音文件,还可以理解bit率的概念
 * ffplay -f s16le -ar 48000 -ac 1 1.data
 */
#define SAMPLE_RATE 48000
#define FREQUENCY   440
#define FRAME_SIZE  1024
typedef struct {
    short data[FRAME_SIZE];
}Frame;
void create_audio(int seconds, Frame **frame, int *framenum);
void print_data(Frame *frame,int framenum);

int main()
{
    Frame *frame=nullptr;
    int framenum=0;
    create_audio(10,&frame,&framenum); //产生10秒音频数据
    print_data(frame,framenum);
    return 0;
}

void create_audio(int seconds, Frame **a_frame, int *a_framenum)
{
    int framenum = seconds * ((SAMPLE_RATE + FRAME_SIZE -1)/ FRAME_SIZE);
    *a_framenum = framenum;
    Frame *frame=0;
    if(*a_frame==nullptr)
    {
        frame = (Frame *)malloc(framenum * sizeof(Frame));
        *a_frame = frame;
    }
    else
    {
        frame =*a_frame;
    }
    float zeta=0; //每一个frame 的初始角度
    int amp=10000; //幅度
    for(int i=0;i<framenum;i++)
    {
        for(int j=0;j<FRAME_SIZE;j++)
        {
            frame[i].data[j]=amp*sin(2*M_PI*FREQUENCY/SAMPLE_RATE*j+zeta); //每一个数据递进一个角度2*PI*FREQUENCY/SAMPLE_RATE,此值为角速度
        }
        zeta += 2*M_PI*FREQUENCY/SAMPLE_RATE*FRAME_SIZE;
    }
    
}
void print_data(Frame *frame,int framenum)
{
    int k=0;
    FILE *fp=fopen("1.data","wb");
    if(!fp){
        printf("error open 1.data\n");
        exit(1);
    }
    for(int i=0;i<framenum; i++)
    {
        for(int j=0; j<FRAME_SIZE;j++)
        {
            printf("%04d ",frame[i].data[j]);
//            fprintf(fp,"%04d",frame[i].data[j]);
            fwrite(&frame[i].data[j],sizeof(short),1,fp);
            k++;
            if(k%16==0) printf("\n");
        }
        printf("\n\n");
    }
    fclose(fp);
}
 

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值