Skip to content
This repository was archived by the owner on Sep 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

81 changes: 39 additions & 42 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,21 @@ exclude = ["assets/*"]

[features]
default = ["std"]
all = ["std", "bevy", "web"]
std = [
"bevy/bevy_asset",
"bevy_platform/std",
"thiserror/std",
"num_enum/std",
"crossbeam-channel/std",
]
all = ["std", "bevy_resources", "web"]
std = ["thiserror/std", "num_enum/std", "crossbeam-channel/std"]
web = ["bevy_platform/web"]
bevy = [
"dep:bevy",
bevy_resources = [
"bevy",
"dep:midir",
"dep:tinyaudio",
"dep:itertools",
"dep:rustysynth",
"dep:crossbeam-channel",
]
debug = ["bevy"]
bevy = ["bevy_resources", "bevy/bevy_log", "std", "bevy/bevy_asset"]
debug = ["bevy_resources"]
example = [
"bevy",
"bevy_resources",
"std",
"bevy/bevy_color",
"bevy/bevy_core_pipeline",
Expand All @@ -46,13 +41,14 @@ example = [
# note that the wasm example freezes since when this feature is not enabled! TODO
"bevy/multi_threaded",
]
serde = ["dep:serde"]


[dependencies.bevy]
version = "0.16"
optional = true
default-features = false
features = ["async_executor", "bevy_log", "bevy_state"]
# features = ["async_executor", "bevy_log", "bevy_state", "bevy_asset", "std"]

[dependencies]
num_enum = { version = "0.7.3", default-features = false }
Expand All @@ -66,6 +62,7 @@ rustysynth = { version = "1.3.5", optional = true }
bevy_platform = { version = "0.16", default-features = false, features = [
"alloc",
] }
serde = {version = "1.0", features = ["derive"], optional = true}

[dev-dependencies]
pretty_assertions = { default-features = false, features = [
Expand All @@ -76,40 +73,40 @@ pretty_assertions = { default-features = false, features = [
# version = "0.16"
# default-features = true

[[example]]
name = "2dpiano"
required-features = ["example"]
# [[example]]
# name = "2dpiano"
# required-features = ["example"]

[[example]]
name = "input"
path = "examples/input/main.rs"
required-features = ["example"]
# [[example]]
# name = "input"
# path = "examples/input/main.rs"
# required-features = ["example"]

[[example]]
name = "input_2dpiano"
path = "examples/input_2dpiano/main.rs"
required-features = ["example"]
# [[example]]
# name = "input_2dpiano"
# path = "examples/input_2dpiano/main.rs"
# required-features = ["example"]

[[example]]
name = "iterate_voices"
required-features = ["example"]
# [[example]]
# name = "iterate_voices"
# required-features = ["example"]

[[example]]
name = "pitchbend"
required-features = ["example"]
# [[example]]
# name = "pitchbend"
# required-features = ["example"]

[[example]]
name = "play_file"
required-features = ["example"]
# [[example]]
# name = "play_file"
# required-features = ["example"]

[[example]]
name = "programmatic_complex_song"
required-features = ["example"]
# [[example]]
# name = "programmatic_complex_song"
# required-features = ["example"]

[[example]]
name = "programmatic_simple_song"
required-features = ["example"]
# [[example]]
# name = "programmatic_simple_song"
# required-features = ["example"]

[[example]]
name = "scale"
required-features = ["example"]
# [[example]]
# name = "scale"
# required-features = ["example"]
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 0 additions & 1 deletion src/bevy/asset/sound_font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ impl SoundFont {
/// Create a new
fn new(file: &mut &[u8]) -> Self {
let sf = Sf::new(file).unwrap();

Self { file: Arc::new(sf) }
}
}
Expand Down
42 changes: 30 additions & 12 deletions src/bevy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,20 +113,38 @@ fn scale_me(synth: Res<Synth>, time: Res<Time>, mut scale: Local<Scale>) {
"#]
#![warn(missing_docs)]

#[cfg(feature = "std")]
pub mod asset;
pub mod input;
pub mod output;
pub mod plugin;
pub mod settings;
pub mod synth;
use bevy::prelude::*;

use crate::bevy::asset::{MidiFile, MidiFileLoader};

//pub mod asset;
// pub mod input;
// pub mod output;
//pub mod plugin;
// pub mod settings;
// pub mod synth;

pub mod song;

/// Commonly re-exported types
pub mod prelude {
pub use crate::bevy::{input::*, output::*, plugin::*, settings::*, song::*, synth::*};
// /// Commonly re-exported types
// pub mod prelude {
// pub use crate::bevy::{input::*, output::*, plugin::*, settings::*, song::*, synth::*};

#[cfg(feature = "std")]
pub use crate::bevy::asset::*;
// #[cfg(feature = "std")]
// pub use crate::bevy::asset::*;
// }

/// Includes the miminal working components
/// of `midix`
///
/// This includes asset loaders for [`MidiFile`]
pub struct MidixMinimalPlugin;

impl Plugin for MidixMinimalPlugin {
fn build(&self, app: &mut App) {
app.init_asset_loader::<MidiFileLoader>()
.init_asset::<MidiFile>();

//todod
}
}
1 change: 1 addition & 0 deletions src/bevy/song/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ impl MidiSong {
pub fn builder() -> MidiSongBuilder {
MidiSongBuilder::default()
}

/// Create a set of commands
pub fn new(events: Vec<Timed<ChannelVoiceMessage>>) -> Self {
Self {
Expand Down
4 changes: 4 additions & 0 deletions src/byte/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ Except for Real-Time messages, new Status bytes will always command a receiver t
even if the last message was not completed.
"#]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StatusByte(u8);

impl core::fmt::Debug for StatusByte {
Expand Down Expand Up @@ -204,6 +206,8 @@ impl TryFrom<u8> for StatusByte {
Data Byte is between [0x00 and 0x7F]
"#]
#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct DataByte(pub(crate) u8);
impl Debug for DataByte {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down
6 changes: 5 additions & 1 deletion src/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ use crate::message::{ChannelVoiceMessage, VoiceEvent};
#[derive(
Clone, Copy, PartialEq, Eq, Debug, Hash, IntoPrimitive, TryFromPrimitive, PartialOrd, Ord,
)]
#[cfg_attr(feature = "bevy", derive(bevy::prelude::Component))]
#[cfg_attr(
feature = "bevy_resources",
derive(bevy::prelude::Component, bevy::prelude::Reflect)
)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(u8)]
pub enum Channel {
/// 0bxxxx0000
Expand Down
9 changes: 9 additions & 0 deletions src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use crate::{prelude::*, reader::ReaderError};
/// in a "coarse" manner.
#[non_exhaustive]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "bevy_resources", derive(bevy::prelude::Reflect))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Controller {
/// 0x00
BankSelection(DataByte),
Expand Down Expand Up @@ -165,4 +167,11 @@ impl Controller {
Other { byte_1, byte_2 } => [byte_1.value(), byte_2.value()],
}
}
/// the damper pedal message
pub fn damper_pedal(value: DataByte) -> Self {
Self::Other {
byte_1: DataByte::new_unchecked(0x40),
byte_2: value,
}
}
}
1 change: 1 addition & 0 deletions src/events/live.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ An emittable message to/from a streaming MIDI device.
There is currently no `StreamReader` type, so this type is most often manually constructed.
"]
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
pub enum LiveEvent<'a> {
/// A MIDI voice message associated with a channel
ChannelVoice(ChannelVoiceMessage),
Expand Down
1 change: 1 addition & 0 deletions src/file/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ sequence number.*/
Holds the tracks based on the supplied format
"#]
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
pub enum Format<'a> {
/// Format 0
SingleMultiChannel(Track<'a>),
Expand Down
1 change: 1 addition & 0 deletions src/file/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::prelude::*;
#[doc = r#"
Information about the timing of the MIDI file
"#]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
pub struct Header {
timing: Timing,
}
Expand Down
8 changes: 8 additions & 0 deletions src/file/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,18 @@ use crate::{
#[doc = r#"
TODO
"#]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
pub struct ParsedMidiFile<'a> {
header: Header,
format: Format<'a>,
}
#[cfg(feature = "bevy")]
impl bevy::asset::Asset for ParsedMidiFile<'static> {}

#[cfg(feature = "bevy")]
impl bevy::asset::VisitAssetDependencies for ParsedMidiFile<'static> {
fn visit_dependencies(&self, _visit: &mut impl FnMut(bevy::asset::UntypedAssetId)) {}
}

impl<'a> ParsedMidiFile<'a> {
/// Parse a set of bytes into a file struct
Expand Down
2 changes: 2 additions & 0 deletions src/file/track.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::{
A set of track events
"#]
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
pub struct Track<'a> {
info: TrackInfo<'a>,
events: Vec<Ticked<LiveEvent<'a>>>,
Expand Down Expand Up @@ -72,6 +73,7 @@ impl<'a> Track<'a> {
/// Provides information about the track
#[allow(missing_docs)]
#[derive(Default, Debug, Clone, PartialEq)]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
pub struct TrackInfo<'a> {
pub time_signature: TimeSignature,
pub name: Option<BytesText<'a>>,
Expand Down
3 changes: 3 additions & 0 deletions src/file_repr/chunk/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ impl RawHeaderChunk {
/// This is either the number of ticks per quarter note or
/// the alternative SMTPE format. See the [`RawHeaderChunk`] docs for more information.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
pub enum Timing {
/// The midi file's delta times are defined using a tick rate per quarter note
TicksPerQuarterNote(TicksPerQuarterNote),
Expand All @@ -123,6 +124,7 @@ pub enum Timing {

/// A representation of the `tpqn` timing for a MIDI file
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
pub struct TicksPerQuarterNote {
inner: [u8; 2],
}
Expand All @@ -136,6 +138,7 @@ impl TicksPerQuarterNote {

/// A representation of the `smpte` timing for a MIDI file
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
pub struct SmpteHeader {
fps: SmpteFps,
ticks_per_frame: DataByte,
Expand Down
1 change: 1 addition & 0 deletions src/file_repr/meta/smpte_offset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{SmpteError, prelude::SmpteFps};

/// A representation of a track's offset from the beginning of a midi file.
#[derive(Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
pub struct SmpteOffset {
/// the track's fps. Note: this should be identical to a file's FPS if
/// the file is defined in terms of `smpte`
Expand Down
1 change: 1 addition & 0 deletions src/file_repr/meta/tempo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
///
/// FF 51 03 tttttt
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
pub struct Tempo(u32);

impl Default for Tempo {
Expand Down
1 change: 1 addition & 0 deletions src/file_repr/meta/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::ParseError;

/// Some text, usually identified by a ['MetaMessage'](super::MetaMessage)s
#[derive(Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
pub struct BytesText<'a> {
inner: Cow<'a, [u8]>,
}
Expand Down
1 change: 1 addition & 0 deletions src/file_repr/meta/time_signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ That is, 6/8 time (8 is 2 to the 3rd power, so this is 06 03),
eight notated 32nd-notes per quarter-note.
"#]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
pub struct TimeSignature([u8; 4]);

impl Default for TimeSignature {
Expand Down
1 change: 1 addition & 0 deletions src/file_repr/smpte.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/// - 29: dropframe 30 (30,000 frames / 1001 seconds)
/// - 30: 30fps
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "bevy_resources", derive(bevy::reflect::Reflect))]
pub enum SmpteFps {
/// 24
TwentyFour,
Expand Down
Loading
Loading