ESP32连接无源喇叭播放音乐

一、乐理准备

十二平均律(12-equal temperament)又称十二等程律。

一个八度分成12份,八个八度的十二平均音率对应的频率如下(从33Hz到7902Hz)。

相邻两个音之间的倍数是2^(1/12),约等于1.0594630943592952645618252949463)。这样一来,高八度的do频率是低八度do的两倍。

频率与钢琴上的按键是对应的:

         CC#DD#EFF#GG#AA#BCC#DD#EFF#GG#AA#BCC#DD#EFF#GG#AA#BCC#DD#EFF#GG#AA#BCC#DD#EFF#GG#AA#BCC#DD#EFF#GG#AA#B               
3335373941444649525558626569737882879298104110117123131139147156165175185196208220233247262277294311330349370392415440466494523554587622659698740784831880932988104711091175124513191397148015681661176018651976209322172349248926372794296031353322352037293951418644354699497852745588592062726645704074597902

我们把频率440赫兹作为中央C ,C调的歌就是把频率440赫兹当作do,乐谱中写作:1=C。

相邻的两个音之间的差一个半音,12345671之间的间隔分别是“全全半全全全半”。

D调的歌就是把从440后面第二个音494赫兹当作do,乐谱中写作1=D。

d697ccb7e5de4fde8313e111ae969442.png

对应的频率就是:(0代表停顿)

83174062274098883174083100 
6227408317406224944407406225540
55462274074083162255449400 
74062255449444049439200  

 加上每个音的时长:

{831,0.3},{740,0.3},{622,0.3},{740,0.3},{988,0.3},{831,0.15},{740,0.15},{831,0.4},{0,0.3},{0,0.3}, 
{622,0.3},{740,0.3},{831,0.3},{740,0.3},{622,0.3},{494,0.15},{440,0.15},{740,0.15},{622,0.15},{554,0.4},{0,0.3},
{554,0.3},{622,0.3},{740,0.3},{740,0.3},{831,0.3},{622,0.15},{554,0.15},{494,0.4},{0,0.3},{0,0.3}, 
{740,0.3},{622,0.3},{554,0.15},{494,0.15},{440,0.15},{494,0.15},{392,0.5},{0,0.3},{0,0.3},  

 

二、代码实现

用的ESP32 WROOM开发板。

struct YINFU{       //定义音符
  int    freq;
  float  Duration;
};
struct YINFU YUEPU[128]={//乐谱就是由音符结构体组成的数组
  {831,0.3},	{740,0.3},	{622,0.3},	{740,0.3},	{988,0.3},	{831,0.15},	{740,0.15},	{831,0.4},	{0,0.3},	{0,0.3},	
  {622,0.3},	{740,0.3},	{831,0.3},	{740,0.3},	{622,0.3},	{494,0.15},	{440,0.15},	{740,0.15},	{622,0.15},	{554,0.4},	{0,0.3},
  {554,0.3},	{622,0.3},	{740,0.3},	{740,0.3},	{831,0.3},	{622,0.15},	{554,0.15},	{494,0.4},	{0,0.3},	{0,0.3},	
  {740,0.3},	{622,0.3},	{554,0.15},	{494,0.15},	{440,0.15},	{494,0.15},	{392,0.5},	{0,0.3},	{0,0.3},		
		
};

完整代码如下:


//定义蜂鸣器控制管脚
#define beep_pin  25   //连无源喇叭

// float k=1.0594631;
struct YINFU{       //定义音符
  int    freq;
  float  Duration;
};
struct YINFU YUEPU[128]={
  {831,0.3},	{740,0.3},	{622,0.3},	{740,0.3},	{988,0.3},	{831,0.15},	{740,0.15},	{831,0.4},	{0,0.3},	{0,0.3},	
  {622,0.3},	{740,0.3},	{831,0.3},	{740,0.3},	{622,0.3},	{494,0.15},	{440,0.15},	{740,0.15},	{622,0.15},	{554,0.4},	{0,0.3},
  {554,0.3},	{622,0.3},	{740,0.3},	{740,0.3},	{831,0.3},	{622,0.15},	{554,0.15},	{494,0.4},	{0,0.3},	{0,0.3},	
  {740,0.3},	{622,0.3},	{554,0.15},	{494,0.15},	{440,0.15},	{494,0.15},	{392,0.5},	{0,0.3},	{0,0.3},		
		
};

void setup() {
  pinMode(beep_pin, OUTPUT);     //设置引脚为输出模式
}

void loop(){
  for(int k=0;k<128;k++){        //顺序演奏128音符
    float d=YUEPU[k].Duration; 
    for(int D=0;D<int(d*YUEPU[k].freq);D++){   //演奏YUEPU[k].freq的音符,时长=d
      if(YUEPU[k].freq != 0){    //演奏音符
        //频率转化为时间间隔,1秒=500000微秒*2。一半高电平,一半低电平,所以用500000/音符频率。
        int freq_to_us=int(500000/YUEPU[k].freq);
        digitalWrite(beep_pin,HIGH); //一半高电平
        delayMicroseconds(freq_to_us);
        digitalWrite(beep_pin,LOW);  //一半低电平
        delayMicroseconds(freq_to_us);
      }
      else{                     //停顿
        digitalWrite(beep_pin,LOW);  //低电平,不发声  
        delayMicroseconds(1000);
      }
    }
  }

}

 

 

 

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值