当前位置:首页 > 科技  > 软件

聊聊使用Rust制作MIDI钢琴程序,你学会了吗?

来源: 责编: 时间:2024-04-29 09:09:15 290观看
导读本文让我们使用Rust实现一个简单的MIDI Piano应用程序。首先,使用以下命令创建一个Rust新项目:cargo new midi-rs然后在Cargo.toml文件中加入依赖项:[dependencies]eframe = "0.27.2"itertools = "0.12.1"phf = { versio

本文让我们使用Rust实现一个简单的MIDI Piano应用程序。csE28资讯网——每日最新资讯28at.com

首先,使用以下命令创建一个Rust新项目:csE28资讯网——每日最新资讯28at.com

cargo new midi-rs

csE28资讯网——每日最新资讯28at.com

然后在Cargo.toml文件中加入依赖项:csE28资讯网——每日最新资讯28at.com

[dependencies]eframe = "0.27.2"itertools = "0.12.1"phf = { version = "0.11", features = ["macros"] }rustysynth = "1.3.1"tinyaudio = "0.1.3"

csE28资讯网——每日最新资讯28at.com

  • eframe:EGUI框架——编写可以编译为web或本机的GUI应用程序
  • itertools:扩展的迭代器适配器、函数和宏。
  • phf:使用完美的散列函数在编译时生成高效的查找表。
  • rustysynth:用纯Rust编写的MIDI 音色库合成器
  • tinyaudio:是一个跨平台,易于使用,底层的音频输出库。

这个应用程序将打开一个接收键盘事件的egui窗口,这些事件被发送到rustysynth库作为midi音符并通过tinyaudio库输出声音。csE28资讯网——每日最新资讯28at.com

首先,在src/main.rs文件中引入这些库:csE28资讯网——每日最新资讯28at.com

use eframe::egui;use itertools::Itertools;use phf::{phf_map, Map};use rustysynth::{SoundFont, Synthesizer, SynthesizerSettings};use std::{    fs::File,    sync::{Arc, Mutex},};use tinyaudio::prelude::*;

csE28资讯网——每日最新资讯28at.com

接下来,定义静态变量和常量:csE28资讯网——每日最新资讯28at.com

const OUTPUT_PARAMS: OutputDeviceParameters = OutputDeviceParameters {    channels_count: 2,    sample_rate: 44100,    channel_sample_count: 441, // 样本的最大长度};#[derive(Debug)]pub struct MidiNote {    pub note: i32,    pub velocity: i32,}pub static NOTE_KEY_MAP: Map<&'static str, MidiNote> = phf_map! {    "A" => MidiNote {        note: 60,        velocity: 100,    },    "S" => MidiNote {        note: 62,        velocity: 100,    },    "D" => MidiNote {        note: 64,        velocity: 100,    },    "F" => MidiNote {        note: 65,        velocity: 100,    },    "G" => MidiNote {        note: 67,        velocity: 100,    },};

csE28资讯网——每日最新资讯28at.com

OUTPUT_PARAMS是tinyaudio的参数。MidiNote持有MIDI音符的音符数和速度,用rustysynth播放它。它们被保存在一个静态映射中,使用一个由按键值索引的phf_map!宏。csE28资讯网——每日最新资讯28at.com

让我们定义SynthApp结构体,它是一个egui应用程序。它有合成器对象和方法来执行音符的开/关,在eframe::App的update方法中处理键盘事件。csE28资讯网——每日最新资讯28at.com

struct SynthApp {    synthesizer: Arc<Mutex<Synthesizer>>,    midi_channel: i32,}impl SynthApp {    fn note_on(&mut self, key: &str) {        let note = match NOTE_KEY_MAP.get(key) {            Some(note) => note,            None => return,        };        self.synthesizer            .lock()            .unwrap()            .note_on(self.midi_channel, note.note, note.velocity)    }    fn note_off(&mut self, key: &str) {        let note = match NOTE_KEY_MAP.get(key) {            Some(note) => note,            None => return,        };        self.synthesizer            .lock()            .unwrap()            .note_off(self.midi_channel, note.note);    }}impl eframe::App for SynthApp {    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {        ctx.input(|i| {            for key_str in NOTE_KEY_MAP.keys() {                if let Some(key) = egui::Key::from_name(key_str) {                    if i.key_pressed(key) {                        self.note_on(key_str);                    } else if i.key_released(key) {                        self.note_off(key_str);                    }                }            }        });        egui::CentralPanel::default().show(ctx, |ui| {            ui.heading("My egui Application");            ui.label(format!("Midi channel {}", self.midi_channel));        });    }}

csE28资讯网——每日最新资讯28at.com

在互联网上有很多不错的音色库,我们使用TimGM6mb.sf2,csE28资讯网——每日最新资讯28at.com

可以在以下地址下载:csE28资讯网——每日最新资讯28at.com

https://github.com/craffel/pretty-midi/blob/main/pretty_midi/TimGM6mb.sf2csE28资讯网——每日最新资讯28at.com

将下载好的文件放入到项目的根目录下。csE28资讯网——每日最新资讯28at.com

最后,我们编写main函数,合成器保存在Arc<Mutex<…>>中,以便run_output_device和SynthApp都可以访问它。csE28资讯网——每日最新资讯28at.com

fn main() -> Result<(), eframe::Error> {    // 加载音色库    let mut sf2 = File::open("TimGM6mb.sf2").unwrap();    let sound_font = Arc::new(SoundFont::new(&mut sf2).unwrap());    // 创建MIDI文件序列器    let settings = SynthesizerSettings::new(OUTPUT_PARAMS.sample_rate as i32);    let synthesizer = Arc::new(Mutex::new(        Synthesizer::new(&sound_font, &settings).unwrap(),    ));    // 运行输出设备    let synth_c = synthesizer.clone();    let mut left: Vec<f32> = vec![0_f32; OUTPUT_PARAMS.channel_sample_count];    let mut right: Vec<f32> = vec![0_f32; OUTPUT_PARAMS.channel_sample_count];    let _device = run_output_device(OUTPUT_PARAMS, move |data| {        synth_c            .lock()            .unwrap()            .render(&mut left[..], &mut right[..]);        for (i, value) in left.iter().interleave(right.iter()).enumerate() {            data[i] = *value;        }    })    .unwrap();    // eframe    let options = eframe::NativeOptions {        viewport: egui::ViewportBuilder::default().with_inner_size([640.0, 480.0]),        ..Default::default()    };    eframe::run_native(        "My egui App",        options,        Box::new(|_cc| {            Box::new(SynthApp {                synthesizer,                midi_channel: 0,            })        }),    )}

csE28资讯网——每日最新资讯28at.com

执行cargo run,结果如图:csE28资讯网——每日最新资讯28at.com

图片图片csE28资讯网——每日最新资讯28at.com

一旦出现窗口,按键盘的ASDFG键,就会播放音符。csE28资讯网——每日最新资讯28at.com

为了进一步探索,你可以通过添加一些UI和乐器来尝试egui和rustysynth的各种功能。csE28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-86352-0.html聊聊使用Rust制作MIDI钢琴程序,你学会了吗?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Python 处理图片的十个库,你知道几个?

下一篇: Python提速秘籍:九个让你的代码飞速运行的巧妙技巧!

标签:
  • 热门焦点
  • 石头智能洗地机A10 Plus体验:双向自清洁治好了我的懒癌

    一、前言和介绍专为家庭请假懒人而生的石头科技在近日又带来了自己的全新旗舰新品,石头智能洗地机A10 Plus。从这个产品名上就不难看出,这次石头推出的并不是常见的扫地机器
  • Rust中的高吞吐量流处理

    作者 | Noz编译 | 王瑞平本篇文章主要介绍了Rust中流处理的概念、方法和优化。作者不仅介绍了流处理的基本概念以及Rust中常用的流处理库,还使用这些库实现了一个流处理程序
  • 分布式系统中的CAP理论,面试必问,你理解了嘛?

    对于刚刚接触分布式系统的小伙伴们来说,一提起分布式系统,就感觉高大上,深不可测。而且看了很多书和视频还是一脸懵逼。这篇文章主要使用大白话的方式,带你理解一下分布式系统
  • 量化指标是与非:挽救被量化指标扼杀的技术团队

    作者 | 刘新翠整理 | 徐杰承本文整理自快狗打车技术总监刘新翠在WOT2023大会上的主题分享,更多精彩内容及现场PPT,请关注51CTO技术栈公众号,发消息【WOT2023PPT】即可直接领取
  • 从零到英雄:高并发与性能优化的神奇之旅

    作者 | 波哥审校 | 重楼作为公司的架构师或者程序员,你是否曾经为公司的系统在面对高并发和性能瓶颈时感到手足无措或者焦头烂额呢?笔者在出道那会为此是吃尽了苦头的,不过也得
  • 零售大模型“干中学”,攀爬数字化珠峰

    文/侯煜编辑/cc来源/华尔街科技眼对于绝大多数登山爱好者而言,攀爬珠穆朗玛峰可谓终极目标。攀登珠峰的商业路线有两条,一是尼泊尔境内的南坡路线,一是中国境内的北坡路线。相
  • 品牌洞察丨服务本地,美团直播成效几何?

    来源:17PR7月11日,美团App首页推荐位出现&ldquo;美团直播&rdquo;的固定入口。在直播聚合页面,外卖&ldquo;神枪手&rdquo;直播间、美团旅行直播间、美团买菜直播间等均已上线,同时
  • 东方甄选单飞:有些鸟注定是关不住的

    文/彭宽鸿编辑/罗卿东方甄选创始人俞敏洪带队的&ldquo;7天甘肃行&rdquo;直播活动已在近日顺利收官。成立后一年多时间里,东方甄选要脱离抖音自立门户的传闻不绝于耳,&ldquo;7
  • 东方甄选单飞:有些鸟注定是关不住的

    作者:彭宽鸿来源:华尔街科技眼&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;东方甄选创始人俞敏洪带队的&ldquo;7天甘肃行&rdquo;直播活动已在近日顺利收官。成立后一
Top