迎接2023,他真的想说“新年快乐”

news2024/9/25 3:26:58

😊你好,我是小航,一个正在变秃、变强的文艺倾年。
🔔2023年快要到来啦,再此祝大家诸事顺遂,所见所盼皆如愿。
🔔本文讲解如何使用Java演奏一首歌曲,一起卷起来叭!
在这里插入图片描述

众所周知,语言=算法+数据结构,那么音乐=曲谱+音质,曲谱定义了音的高低、长短,力度,我们常常又根据这些对歌曲常分为主奏和伴奏。因为一切皆文件嘛,凭借这些规则,我们通过编程将曲谱读取得到对应的音符的高低、长短、力度,然后依次调用音质文件,最后组成音乐。

先上视频演示,代码在文末:

演奏视频


目录

    • 1、音质
    • 2、编写主奏、伴奏曲谱
    • 3、编写项目

1、音质

主奏与伴奏中支持输入的35个音符:
“1–” ~ “7–”, “1-” ~ “7-”, “1” ~ “7”, “1+” ~ “7+”, “1++” ~ “7++” 分别代表倍低音、低音、中音、高音、倍高音一共35个音符

这里我们提前找到对应的音(音色可以自己找,上网一搜八十八个高音音频即可):

在这里插入图片描述

2、编写主奏、伴奏曲谱

2、分别在主奏(.note)与伴奏(.accompaniments)中输入需要自动弹奏的音符,定义规则如下:

  • 每个音符之间用空格隔开(任意多个空格,推荐每个音符包括空格共占用4个占位符,以便主奏和伴奏音符对齐)

  • 输入字符"0",则会使音长额外延长一倍;

  • 输入除了上面35个音符以及“0”以外的任意字符不会对弹奏起任何作用;

  • 如果需要换行填写,则需在上一行的末尾以及下一行的开头都加上空格;

  • 音长里输入每两个音符之间的间隔时长,单位是毫秒(ms)

这里我找了一份蜜雪冰城的谱子:
在这里插入图片描述
然后将它转化为咱们的规则:
主旋律:

 0     0 3+ 4+ 
 5+ 0 5+ 0 5+   0 0   6+ 
 5+ 0 3+ 0 1+   0 1+ 2+ 
 3+ 0 3+ 0 2+   0 2+ 0 
 1+ 0 0   0 1++ 0 0   0 

 3+ 0 5+ 0 5+ 0 0 6+ 
 5+ 0 3+ 0 1+ 0 1+ 2+ 
 3+ 0 3+ 0 2+ 0 1+ 0 
 2+ 0 0 0 0 0 0 0 

 3+ 0 5+ 0 5+ 0 0 6+ 
 5+ 0 3+ 0 1+ 0 1+ 2+ 
 3+ 0 3+ 0 2+ 0 2+ 0 
 1+ 0 0 0 0 0 0 0 

 4+ 0 0 0 4+ 0 0 0 
 4+ 0 6+ 0 0 0 0 0 
 5+ 0 0 0 5+ 0 3+ 0 
 2+ 0 0 0 0 0 0 0 

 3+ 0 5+ 0 5+ 0 0 6+ 
 5+ 0 3+ 0 1+ 0 1+ 2+ 
 3+ 0 3+ 0 2+ 0 2+ 0 
 1+ 0 0 0 0 0 0 0 

伴奏:

 0   0 0  0 
 1- 0 3- 0 1-  0 3- 0 
 1- 0 3- 0 1-  0 3- 0 
 1- 0 3- 0 5-- 0 2- 0 
 1- 0 3- 0 3-  0 0 0 

 1- 0 3- 0 1-  0 3- 0 
 1- 0 3- 0 1-  0 3- 0 
 1- 0 3- 0 1-  0 3- 0 
 5-- 0 2- 0 5-- 0 2- 0 

 1- 0 3- 0 1-  0 3- 0 
 1- 0 3- 0 1-  0 3- 0 
 1- 0 3- 0 5-- 0 2- 0 
 1- 0 3- 0 1- 0 3- 0 

 4-- 0 1- 0 4-- 0 1- 0 
 4-- 0 1- 0 4-- 0 1- 0 
 1- 0 3- 0 1- 0 3- 0 
 5-- 0 2- 0 5-- 0 2- 0 

 1- 0 3- 0 1- 0 3- 0 
 1- 0 3- 0 1- 0 3- 0 
 1- 0 3- 0 5-- 0 2- 0 
 1- 0 3- 0 1++ 0 0 0 

3、编写项目

我们新建Maven项目并将上述文件分别放到resoucres目录下:
在这里插入图片描述
导入需要的依赖:

		<dependency>
            <groupId>javazoom</groupId>
            <artifactId>jlayer</artifactId>
            <version>1.0.1</version>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-core</artifactId>
            <version>5.6.5</version>
        </dependency>

编写启动类,类名叫Happpy叭:

public class Happy {
    public static void main(String[] args) {
        String musicName = "蜜雪冰城";
        FileUtils.play(musicName);
    }
}

编写FileUtils(实现读取曲谱的功能)

public class FileUtils {
    static void play(String musicName) {
        System.out.println("载入歌曲:" + musicName);
        String path =
                new File("").getAbsolutePath() + File.separator + "src/main/resources/notes" + File.separator;
        String notesPath = path + musicName +  ".notes";
        String accompanimentsPath = path + musicName +  ".accompaniments";
        String notes = fileToStr(notesPath);
        String accompaniments = fileToStr(accompanimentsPath);
        new AudioPlay(180).loadNotes(notes).start();
        new AudioPlay(180).loadNotes(accompaniments).start();
        new Animation(180).loadNotes(notes).start();
    }

    static String fileToStr(String musicPath) {
        StringBuilder stringBuilder = new StringBuilder();
        try {
            BufferedReader reader = new BufferedReader(new FileReader(musicPath));
            String line = null;
            String ls = System.getProperty("line.separator");
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
                stringBuilder.append(ls);
            }
            // 删除最后一个新行分隔符
            stringBuilder.deleteCharAt(stringBuilder.length() - 1);
            reader.close();
        } catch (Exception ignored) {}
        return stringBuilder.toString();
    }
}

规则编写:
新建AudioPlay类,将每个音符对应每个读取到的字符:

package com.example.demo.play;

import cn.hutool.core.io.FileUtil;

/**
 * @author xh
 * @Date 2022/12/27
 */
public class AudioPlay extends Thread{
    /** 音符 */
    private String[] notes;
    /** 间隔时间(单位:毫秒) */
    private int times;


    public AudioPlay(String[] notes, int times)
    {
        this.notes = notes;
        this.times = times;
    }

    public AudioPlay(String filePath, int times)
    {
        String content = FileUtil.readString(filePath,"UTF-8");
        this.notes = content.split(" ");
        this.times = times;
    }

    public AudioPlay(int times)
    {
        this.times = times;
    }


    public String[] getNotes()
    {
        return this.notes;
    }


    public void setNotes(String[] notes)
    {
        this.notes = notes;
    }
    public AudioPlay loadNotes(String notes)
    {
        this.notes = notes.split(" ");
        return this;
    }


    public int getTimes()
    {
        return this.times;
    }


    public void setTimes(int times)
    {
        this.times = times;
    }


    @Override
    public void run()
    {
        try
        {
            int times = this.times;
            new Audio("audio/test.mp3").start();
            sleep(1000);
            for (String note : notes) {
                if (note.length() < 1) {
                    continue;
                }
                switch (note) {
                    case "1--":
                        new Audio("audio/ll1.mp3").start();
                        sleep(times / 2);
                        break;
                    case "2--":
                        new Audio("audio/ll2.mp3").start();
                        sleep(times / 2);
                        break;
                    case "3--":
                        new Audio("audio/ll3.mp3").start();
                        sleep(times / 2);
                        break;
                    case "4--":
                        new Audio("audio/ll4.mp3").start();
                        sleep(times / 2);
                        break;
                    case "5--":
                        new Audio("audio/ll5.mp3").start();
                        sleep(times / 2);
                        break;
                    case "6--":
                        new Audio("audio/ll6.mp3").start();
                        sleep(times / 2);
                        break;
                    case "7--":
                        new Audio("audio/ll7.mp3").start();
                        sleep(times / 2);
                        break;
                    case "1-":
                        new Audio("audio/l1.mp3").start();
                        sleep(times / 2);
                        break;
                    case "2-":
                        new Audio("audio/l2.mp3").start();
                        sleep(times / 2);
                        break;
                    case "3-":
                        new Audio("audio/l3.mp3").start();
                        sleep(times / 2);
                        break;
                    case "4-":
                        new Audio("audio/l4.mp3").start();
                        sleep(times / 2);
                        break;
                    case "5-":
                        new Audio("audio/l5.mp3").start();
                        sleep(times / 2);
                        break;
                    case "6-":
                        new Audio("audio/l6.mp3").start();
                        sleep(times / 2);
                        break;
                    case "7-":
                        new Audio("audio/l7.mp3").start();
                        sleep(times / 2);
                        break;
                    case "1":
                        new Audio("audio/m1.mp3").start();
                        sleep(times / 2);
                        break;
                    case "2":
                        new Audio("audio/m2.mp3").start();
                        sleep(times / 2);
                        break;
                    case "3":
                        new Audio("audio/m3.mp3").start();
                        sleep(times / 2);
                        break;
                    case "4":
                        new Audio("audio/m4.mp3").start();
                        sleep(times / 2);
                        break;
                    case "5":
                        new Audio("audio/m5.mp3").start();
                        sleep(times / 2);
                        break;
                    case "6":
                        new Audio("audio/m6.mp3").start();
                        sleep(times / 2);
                        break;
                    case "7":
                        new Audio("audio/m7.mp3").start();
                        sleep(times / 2);
                        break;
                    case "1+":
                        new Audio("audio/h1.mp3").start();
                        sleep(times / 2);
                        break;
                    case "2+":
                        new Audio("audio/h2.mp3").start();
                        sleep(times / 2);
                        break;
                    case "3+":
                        new Audio("audio/h3.mp3").start();
                        sleep(times / 2);
                        break;
                    case "4+":
                        new Audio("audio/h4.mp3").start();
                        sleep(times / 2);
                        break;
                    case "5+":
                        new Audio("audio/h5.mp3").start();
                        sleep(times / 2);
                        break;
                    case "6+":
                        new Audio("audio/h6.mp3").start();
                        sleep(times / 2);
                        break;
                    case "7+":
                        new Audio("audio/h7.mp3").start();
                        sleep(times / 2);
                        break;
                    case "1++":
                        new Audio("audio/hh1.mp3").start();
                        sleep(times / 2);
                        break;
                    case "2++":
                        new Audio("audio/hh2.mp3").start();
                        sleep(times / 2);
                        break;
                    case "3++":
                        new Audio("audio/hh3.mp3").start();
                        sleep(times / 2);
                        break;
                    case "4++":
                        new Audio("audio/hh4.mp3").start();
                        sleep(times / 2);
                        break;
                    case "5++":
                        new Audio("audio/hh5.mp3").start();
                        sleep(times / 2);
                        break;
                    case "6++":
                        new Audio("audio/hh6.mp3").start();
                        sleep(times / 2);
                        break;
                    case "7++":
                        new Audio("audio/hh7.mp3").start();
                        sleep(times / 2);
                        break;
                    case "0":
                        sleep(times / 2);
                        break;
                    default:
                        continue;
                }
                sleep(times / 2);
                times = this.times;
            }

        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }

    }

}

读取曲谱文件并打印曲谱:

package com.example.demo.play;

/**
 * @author xh
 * @Date 2022/12/27
 */
public class Animation extends Thread{
    /** 音符 */
    private String[] notes;
    /** 间隔时间(单位:毫秒) */
    private int times;

    public Animation(int times) {
        this.times = times;
    }

    public Animation(String[] notes, int times) {
        this.notes = notes;
        this.times = times;
    }

    public String[] getNotes() {
        return this.notes;
    }

    public void setNotes(String[] notes) {
        this.notes = notes;
    }

    public int getTimes() {
        return this.times;
    }

    public void setTimes(int times) {
        this.times = times;
    }

    public Animation loadNotes(String notes) {
        this.notes = notes.split(" ");
        return this;
    }

    @Override
    public void run() {
        try {
            int times = this.times;
            new Audio("audio/test.mp3").start();
            sleep(1000);
            int no = 1;
            for (String note : this.notes) {
                if (note.length() < 1) {
                    continue;
                }
                // 3+ 0 3+ 3+ 3+ 3+ 0 3+ 3+ 3+ 4+ 2+ 0 2+ 2+ 2+ 2+ 0 2+ 2+ 2+ 3+ 1+
                String n = note.replace("+", "").replace("-", "");
                if ("\n".equals(n) || "\r".equals(n) || "\r\n".equals(n)) {
                    System.out.print("\n");
                    no++;
                    continue;
                }
                switch (n) {
                    case "0":
                        System.out.print("_");
                        break;
                    case "1":
                        System.out.print("▁");
                        break;
                    case "2":
                        System.out.print("▂");
                        break;
                    case "3":
                        System.out.print("▃");
                        break;
                    case "4":
                        System.out.print("▄");
                        break;
                    case "5":
                        System.out.print("▅");
                        break;
                    case "6":
                        System.out.print("▆");
                        break;
                    case "7":
                        System.out.print("▇");
                        break;
                }
                System.out.print(" ");
                sleep(times);
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

    }

}

控制音频播放Audio类:

package com.example.demo.play;

import cn.hutool.core.io.resource.ResourceUtil;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.Player;

import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author xh
 * @Date 2022/12/27
 */
public class Audio {
    private static InputStream is;
    private Player player;
    ExecutorService service = Executors.newCachedThreadPool();

    public Audio(String path)
    {
        is = ResourceUtil.getStream(path);
        try
        {
            player = new Player(is);
        }
        catch (JavaLayerException e)
        {
            e.printStackTrace();
        }
    }


    public void start()
    {
        service.submit(() -> {
            try
            {
                player.play();
            }
            catch (JavaLayerException ignored)
            {

            }
        });

    }
}

项目整体结构:
在这里插入图片描述

代码已经开源到Github上,欢迎大家玩!传送门

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/131641.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Faster RCNN网络源码解读(Ⅶ) --- RPN网络代码解析(中)RegionProposalNetwork类解析

目录 一、代码作用&#xff08;rpn_function.py&#xff09; 二、代码解析 2.1 RegionProposalNetwork类 2.1.1 初始化函数__init__ 2.1.2 正向传播过程forward 2.1.3 concat_box_prediction_layers函数 2.1.4 permute_and_flatten 2.1.5 filter_proposals 2.1.6 _…

2022 许些遗憾 年终总结

目录回首过去展望未来验收 2022年任务清单 ---------------------------》 2023年 flag2023 展望回首过去 此刻&#xff0c;想想这一年&#xff0c;口罩&#xff0c;38.5℃&#xff0c;艰难时刻&#xff0c;终究在2022最后十天被确诊了“阳”&#xff0c;没有备任何药&#xff…

Linux系列——Linux操作系统安装及服务控制(1)

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.Linux介绍 1.Linux是什么&#xff1f; 2.Linux系统的优点 …

ArcGIS基础实验操作100例--实验31纠正栅格坐标

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验31 纠正栅格坐标 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&…

2023新年祝福代码[css动画特效]

目录 前言 一、jQuery之家 二、2023新年祝福页面 2.1 我的博客和祝福语 2.2 我的博客头像和动态烟花 ​编辑 2.3 背景为动图 三、完整效果图 总结 前言 心态还需努力呀在这里祝大家新的一年里愿望都能实现。2022年已经过去&#xff0c;2022年的遗憾、不开心&#xff…

Spring学习笔记(1)

Spring系统架构 Spring Framework是Spring生态圈中最基础的项目&#xff0c;是其他项目的根基。 Spring Framework系统架构 学习线路 核心概念 IoC( Inversion of Control )控制反转 使用对象时&#xff0c;由主动new产生对象转换为由外部提供对象&#xff0c;此过程中对象…

DoIP协议从入门到精通—Alive check

惯例,为避免自己成为高知识低文化的汉子,分享一段喜欢的文字: 一、Socket 概念 在DoIP(Diagnostic on IP)概念中,通信的核心是Socket(套接字,实际通信的载体),是车载以太网在诊断范畴进行通信的句柄,Socket是支持TCP/IP协议的网络通信的基本操作单元。对于Socket: …

python多进程的理解 multiprocessing Process join run

最近看了下多进程。 一种接近底层的实现方法是使用 os.fork()方法&#xff0c;fork出子进程。但是这样做事有局限性的。比如windows的os模块里面没有 fork() 方法。 windows&#xff1a; 。linux&#xff1a; 另外还有一个模块&#xff1a;subprocess。这个没整过&#xff0c…

Canvas学习笔记 | 图片操作

图片素材 本篇文章的示例采用下图进行图片操作演示。 图片原始尺寸为&#xff1a;640px * 640px。 绘制图片 在Canvas中&#xff0c;我们使用drawImage()方法绘制图片。drawImage()方法有如下3种调用方式&#xff1a; 1.drawImage(image, dx, dy) 2.drawImage(image, dx, d…

【Android】带你细看Android input系统中ANR的机制

“本文基于Android13源码&#xff0c;分析Input系统的Anr实现原理“ 在文章之前&#xff0c;先提几个问题&#xff1a; 如果在activity任意周期&#xff08;onCreate,onResume等&#xff09;&#xff0c;同步执行耗时超过5s&#xff08;ANR时间&#xff09;的任务&#xff0c;…

JavaWeb06 AJAX 黑马用Axios实现用户名已存在问题? JSON Vue Element

01-AJAX-概述-替换JSP 02-AJAX-快速入门 03-案例-验证用户是否存在 04-Axios-基本使用&请求方式别名(可读性不强) 练习:用Axios替换AJAX实现用户名是否存在功能 就把原来的.html 2.2步换成下面的响应代码即可 为啥就是不行呢????? 05-JSON-概述和基础语法 06-JSON-…

并发编程——4.共享模型之内存

目录4.共享模型之内存4.1.Java 内存模型4.2.可见性4.2.1.退不出的循环4.2.2.解决办法4.2.3.可见性 vs 原子性4.3.终止模式之两阶段终止模式4.3.1.错误思路4.3.2.两阶段终止模式4.4.同步模式之 Balking4.4.1.定义4.4.2.实现4.5.有序性4.5.1.指令级并行原理4.5.2.案例4.6.原理之 …

LVS详解

一、负载均衡&#xff1a;必不可少的基础手段 1.1 找更多的牛来拉车吧 当前大多数的互联网系统都使用了服务器集群技术&#xff0c;集群即将相同服务部署在多台服务器上构成一个集群整体对外提供服务&#xff0c;这些集群可以是Web应用服务器集群&#xff0c;也可以是数据库服务…

新冠“照妖镜”,体质弱点现原形。你是啥症状?2023年,请好好善待你的身体!

新冠“照妖镜”&#xff0c;体质弱点现原形。你是啥症状&#xff1f; 阳性之后的不同症状&#xff0c;是我们身体发出的【预警信号】。 病毒进入时&#xff0c;最先攻击我们自身最薄弱的地方。 2023年&#xff0c;请好好【善待】你的身体&#xff01; 症状1 、头疼 出现头痛…

Kurganov-Tadmor二阶中心格式:理论介绍

简介 CFD的核心问题是求解双曲偏微分方程 ∂∂tu(x,t)∂∂xf(u(x,t))0\frac{\partial}{\partial t} u(x, t)\frac{\partial}{\partial x} f(u(x, t))0 ∂t∂​u(x,t)∂x∂​f(u(x,t))0在CFD中&#xff0c;双曲偏微分方程一般使用Godunov型迎风格式求解。但是这种迎风格式往往实…

2022年度学习总结

2022年有焦虑也有成长&#xff0c;记录和总结也是成长的一部分。这一年&#xff0c;我也努力在不确定性中做一些确定的事情&#xff0c;感恩被保护的三年&#xff0c;三年清零抗疫结束&#xff0c;做好自己健康的第一责任人。研一半个学期在网课或者封校中度过&#xff0c;我们…

1.0、Linux-入门概述

1.0、Linux-入门概述 我们为什么要学习 Linux &#xff1f; Linux诞生了这么多年&#xff0c;以前还喊着如何能取代 Windows 系统&#xff0c;现在这个口号已经小多了&#xff0c;任何事物发展都有其局限性&#xff1b;如同现在国内在搞一个社交软件取代 QQ 、微信 一样&#x…

已解决(Python语法报错)SyntaxError: invalid syntax

已解决&#xff08;Python语法报错&#xff09;SyntaxError: invalid syntax 文章目录报错信息报错翻译报错原因解决方法帮忙解决报错信息 粉丝群里面一个小伙伴运行Python代码&#xff0c;但是发生了报错&#xff08;当时他心里瞬间凉了一大截&#xff0c;跑来找我求助&…

IDEA安装与配置教程

一、下载并安装IDEA 1、下载官网&#xff1a; 下载 IntelliJ IDEA &#xff08;这里以Windows系统为例&#xff0c;其他系统类似&#xff09; 2、安装 1、下载完成后&#xff0c;直接点击安装包安装&#xff0c;即可。 2、开始安装&#xff0c;然后下一步 3、可以在此处自定…

算法 - 蓝桥杯并查集题型

目录 合并集合 连通块中点的数量 蓝桥杯2017年第八届真题-合根植物 [蓝桥杯][2019年第十届真题] 修改数组 蓝桥幼儿园 刷了好多题&#xff0c;发现并查集这种思想挺妙的&#xff0c;是时候总结一下了&#xff1b; 作用与基本原理&#xff1a; 套路问题&#xff1a; 用一道…