TonePlayer音调播放器开发

音调播放器

           根据蜂鸣器的声音频率、播放长短和声音大小,来产生设备需要的音频:比如设备启动声音、设备关机音、故障音、连接成功音、断开连接音、信号不稳定提示音、充电启动提示音、充电关闭提示音、设备插入提示音、设备拔出提示音、无操作提示音以及需要的音乐(八音盒播放的那种声音);

参考:[11-2] 蜂鸣器播放提示音&音乐_哔哩哔哩_bilibili
补充:

#表示右侧的符号转化为字符串
##表示将左右的符号拼接在一起。例如拼接变量名MUSIC_DEF(name)等同MUSIC_DEF_name 

eg. 
#define ADD_MUSIC(mc) {Music_##mc,(sizeof(Music_##mc) / sizeof(Music_##mc[0])), #mc}
               ADD_MUSIC(Startup), // 等价 {ADD_MUSIC_Startup , 3 , "Startup" },
现在定义相关的设备启动声音、设备关机音、故障音、连接成功音、断开连接音、信号不稳定提示音、充电启动提示音、充电关闭提示音、设备插入提示音、设备拔出提示音、无操作提示音,音乐表如下:
 

#include "ToneMap.h"
//##表示将左右的符号拼接在一起。例如拼接变量名MUSIC_DEF(name)等同MUSIC_DEF_name
#define MUSIC_DEF(name) static const TonePlayer::MusicNode_t Music_##name[] =

/*开机音 MUSIC_DEF_Startup[]={}; */
MUSIC_DEF(Startup)
{
    {M1, 80},
    {M6, 80},
    {M3, 80},
};

/*关机音*/
MUSIC_DEF(Shutdown)
{
    {M3, 80},
    {M6, 80},
    {M1, 80},
};

/*错误提示音*/
MUSIC_DEF(Error)
{
    {100, 80},
    {0,   80},
    {100, 80},
};

/*连接成功音*/
MUSIC_DEF(Connect)
{
    {H1, 80},
    {H2, 80},
    {H3, 80},
};

/*断开连接音*/
MUSIC_DEF(Disconnect)
{
    {H3, 80},
    {H2, 80},
    {H1, 80},
};

/*信号不稳定提示音*/
MUSIC_DEF(UnstableConnect)
{
    {H1, 80},
    {0, 80},
    {H1, 80},
};

/*充电启动提示音*/
MUSIC_DEF(BattChargeStart)
{
    {L1, 80},
    {L3, 80},
};

/*充电关闭提示音*/
MUSIC_DEF(BattChargeEnd)
{
    {L3, 80},
    {L1, 80},
};

/*设备插入提示音*/
MUSIC_DEF(DeviceInsert)
{
    /*C4,A3,F3,F4*/
    {M1, 180},
    {L6, 80},
    {L4, 80},
    {M4, 160},
};

/*设备拔出提示音*/
MUSIC_DEF(DevicePullout)
{
    /*A4,F4,E4*/
    {L6, 80},
    {L4, 80},
    {L3, 80},
};

/*无操作提示音*/
MUSIC_DEF(NoOperationWarning) 
{
    {4000, 40},
    {0, 80},
    {4000, 40},
    {0, 80},
    {4000, 40},
};

/*列表数据类型定义*/
typedef struct
{
    const TonePlayer::MusicNode_t* mc;
    uint16_t length;
    const char* name;
} MusicList_t;
//#表示右侧的符号转化为字符串
//ADD_MUSIC(mc) {ADD_MUSIC_mc , 成员数 ,"mc" } 
#define ADD_MUSIC(mc) {Music_##mc,(sizeof(Music_##mc) / sizeof(Music_##mc[0])), #mc}

/*提示音地址储存列表*/
static const MusicList_t MusicList[] =
{
    ADD_MUSIC(Startup), // 等价 {ADD_MUSIC_Startup , 3 , "Startup" },
    ADD_MUSIC(Shutdown),
    ADD_MUSIC(Error),
    ADD_MUSIC(Connect),
    ADD_MUSIC(Disconnect),
    ADD_MUSIC(UnstableConnect),
    ADD_MUSIC(BattChargeStart),
    ADD_MUSIC(BattChargeEnd),
    ADD_MUSIC(DeviceInsert),
    ADD_MUSIC(DevicePullout),
    ADD_MUSIC(NoOperationWarning),
};

音符频率列表

/*音符频率对应表*/
enum ToneMap
{
    L1 = 262,
    L1h = 277,
    L2 = 294,
    L2h = 311,
    L3 = 330,
    L4 = 349,
    L4h = 370,
    L5 = 392,
    L5h = 415,
    L6 = 440,
    L6h = 466,
    L7 = 494,
    M1 = 523,
    M1h = 554,
    M2 = 587,
    M2h = 622,
    M3 = 659,
    M4 = 698,
    M4h = 740,
    M5 = 784,
    M5h = 831,
    M6 = 880,
    M6h = 932,
    M7 = 988,
    H1 = 1046,
    H1h = 1109,
    H2 = 1175,
    H2h = 1245,
    H3 = 1318,
    H4 = 1397,
    H4h = 1480,
    H5 = 1568,
    H5h = 1661,
    H6 = 1760,
    H6h = 1865,
    H7 = 1976,
};

TonePlayer.cpp 

#include "TonePlayer.h"

TonePlayer::TonePlayer()
{
    CallbackFunction = nullptr;
    CurrentMusic = nullptr;
    Speed = SPEED_NORMAL;
}

void TonePlayer::SetMusic(const MusicNode_t* music, uint16_t length)
{
    if (music == CurrentMusic)
    {
        return;
    }

    CurrentMusic = music;
    Length = length;
    CurrentPos = length;
}

void TonePlayer::SetSpeed(uint16_t speed)
{
    Speed = speed;
}

void TonePlayer::Play()
{
    CurrentPos = 0;
}

void TonePlayer::Stop()
{
    CurrentPos = Length;
}

bool TonePlayer::Update(uint32_t tick)
{
    if (CallbackFunction == nullptr)
    {
        return false;
    }

    if(CurrentPos < Length)
    {
        if(tick > NextTime)
        {
            CallbackFunction(CurrentMusic[CurrentPos].Freq, CurrentMusic[CurrentPos].Volume);

            NextTime = tick + CurrentMusic[CurrentPos].Time * Speed / SPEED_NORMAL;
            CurrentPos++;
        }
        return true;
    }
    else if(CurrentPos == Length && tick > NextTime)
    {
        CallbackFunction(0, 0);
        CurrentPos++;
    }

    return false;
}

TonePlayer.h

#include <stdint.h>

class TonePlayer
{
    typedef void(*CallbackFunction_t)(uint32_t, uint16_t);
public:
    //音乐链表
    typedef struct
    {
        uint16_t Freq;//频率
        uint16_t Time;//时长
        uint16_t Volume;//音量
    } MusicNode_t;
    //速度
    enum Speed
    {
        SPEED_HALF = 512,
        SPEED_NORMAL = 256,
        SPEED_DOUBLE = 128
    };

    TonePlayer();
    ~TonePlayer() {}
    void SetMusic(const MusicNode_t* music, uint16_t length);
    void SetCallback(CallbackFunction_t func)
    {
        CallbackFunction = func;
    }
    void Play();
    void Play(const MusicNode_t* music, uint16_t length)
    {
        SetMusic(music, length);
        Play();
    }
    void Stop();
    void SetSpeed(uint16_t speed);
    bool Update(uint32_t tick);
private:
    uint16_t Length;
    uint16_t CurrentPos;
    uint32_t NextTime;
    uint16_t Speed;
    const MusicNode_t* CurrentMusic;
    CallbackFunction_t CallbackFunction;
};

回调函数定义

 沦陷更新控制蜂鸣器

  • 14
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaoxilang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值