Compare commits

..

No commits in common. "d34c3d6e9640993051a91cce93596d80c30fac2d" and "4c1471c2abed1003815ccc4adba61f6fcc514979" have entirely different histories.

4 changed files with 59 additions and 79 deletions

View File

@ -2,22 +2,6 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## Version 0.5.0 - 2024-02-09
### Bug Fixes
- Clean up `LastAudio` when `Sound` is removed, not `Source`.
### Features
- [**breaking**] Renamed `SynthizerSets::First` to `SynthizerSets::PreUpdate` and moved remaining systems into `PostUpdate`.
- [**breaking**] Removed `Sound.restart`. Clear `Sound.generator` for equivalent functionality.
### Miscellaneous Tasks
- Clean up code.
- Bump dependencies.
## Version 0.4.0 - 2023-07-16 ## Version 0.4.0 - 2023-07-16
### Miscellaneous Tasks ### Miscellaneous Tasks

View File

@ -1,6 +1,6 @@
[package] [package]
name = "bevy_synthizer" name = "bevy_synthizer"
version = "0.5.0" version = "0.4.0"
authors = ["Nolan Darilek <nolan@thewordnerd.info>"] authors = ["Nolan Darilek <nolan@thewordnerd.info>"]
description = "A Bevy plugin for Synthizer, a library for 3D audio and synthesis with a focus on games and VR applications" description = "A Bevy plugin for Synthizer, a library for 3D audio and synthesis with a focus on games and VR applications"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
@ -10,11 +10,12 @@ repository = "https://labs.lightsout.games/projects/bevy_synthizer"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
bevy = { version = "0.12", default-features = false, features = ["bevy_asset"] } anyhow = "1"
bevy = { version = "0.11", default-features = false, features = ["bevy_asset"] }
synthizer = "0.5.6" synthizer = "0.5.6"
[dev-dependencies] [dev-dependencies]
bevy = { version = "0.12", default-features = true } bevy = { version = "0.11", default-features = true }
[package.metadata.release] [package.metadata.release]
publish = false publish = false

View File

@ -1,6 +1,6 @@
use std::f32; use std::f32;
use bevy::{asset::LoadedFolder, prelude::*}; use bevy::{asset::LoadState, prelude::*};
use bevy_synthizer::*; use bevy_synthizer::*;
#[derive(Component, Deref, DerefMut)] #[derive(Component, Deref, DerefMut)]
@ -12,40 +12,45 @@ impl Default for RotationTimer {
} }
} }
#[derive(Resource, Default, Deref, DerefMut)] #[derive(Resource, Default)]
struct AssetHandles(Handle<LoadedFolder>); struct AssetHandles {
sounds: Vec<HandleUntyped>,
loaded: bool,
}
fn setup(asset_server: Res<AssetServer>, mut handles: ResMut<AssetHandles>) { fn setup(asset_server: Res<AssetServer>, mut handles: ResMut<AssetHandles>) {
**handles = asset_server.load_folder("."); handles.sounds = asset_server.load_folder(".").expect("Failed to load sfx");
} }
fn load_and_create( fn load_and_create(
mut commands: Commands, mut commands: Commands,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
handles: Res<AssetHandles>, mut handles: ResMut<AssetHandles>,
listeners: Query<&Listener>,
) { ) {
if !asset_server.is_loaded_with_dependencies(&**handles) { if handles.loaded {
return; return;
} }
if !listeners.is_empty() { handles.loaded = asset_server
return; .get_group_load_state(handles.sounds.iter().map(|handle| handle.id()))
== LoadState::Loaded;
if handles.loaded {
commands.spawn((
TransformBundle::default(),
Listener,
RotationTimer::default(),
));
let handle = handles.sounds[0].clone();
let buffer = asset_server.get_handle(handle);
commands.spawn((
TransformBundle::from(Transform::from_translation(Vec3::new(10., 0., 0.))),
Source::default(),
Sound {
audio: buffer.into(),
looping: true,
..default()
},
));
} }
commands.spawn((
TransformBundle::default(),
Listener,
RotationTimer::default(),
));
let handle = asset_server.load("footstep.wav");
commands.spawn((
TransformBundle::from(Transform::from_translation(Vec3::new(10., 0., 0.))),
Source::default(),
Sound {
audio: handle.into(),
looping: true,
..default()
},
));
} }
fn rotate_listener(time: Res<Time>, mut query: Query<(&mut RotationTimer, &mut Transform)>) { fn rotate_listener(time: Res<Time>, mut query: Query<(&mut RotationTimer, &mut Transform)>) {

View File

@ -2,48 +2,39 @@
use std::collections::HashMap; use std::collections::HashMap;
use bevy::{ use bevy::{
asset::{io::Reader, AssetLoader, AsyncReadExt, LoadContext}, asset::{AssetLoader, LoadContext, LoadedAsset},
prelude::*, prelude::*,
reflect::TypePath, reflect::{TypePath, TypeUuid},
transform::TransformSystem, transform::TransformSystem,
utils::{ utils::BoxedFuture,
thiserror::{self, Error},
BoxedFuture,
},
}; };
pub use synthizer as syz; pub use synthizer as syz;
#[derive(Asset, Clone, Debug, Deref, DerefMut, PartialEq, Eq, TypePath)] #[derive(Clone, Debug, Deref, DerefMut, PartialEq, Eq, TypePath, TypeUuid)]
#[uuid = "6b6b533a-bb1f-11ec-bda2-00155d8fdde9"]
pub struct Buffer(syz::Buffer); pub struct Buffer(syz::Buffer);
#[derive(Clone, Copy, Debug, Default)] #[derive(Clone, Copy, Debug, Default)]
struct BufferAssetLoader; struct BufferAssetLoader;
#[non_exhaustive]
#[derive(Debug, Error)]
pub enum BufferAssetLoaderError {
#[error("Could not load asset: {0}")]
Io(#[from] std::io::Error),
#[error("Synthizer error: {0}")]
SynthizerError(#[from] synthizer::Error),
}
impl AssetLoader for BufferAssetLoader { impl AssetLoader for BufferAssetLoader {
type Asset = Buffer;
type Settings = ();
type Error = BufferAssetLoaderError;
fn load<'a>( fn load<'a>(
&'a self, &'a self,
reader: &'a mut Reader, bytes: &'a [u8],
_settings: &'a (), load_context: &'a mut LoadContext,
_load_context: &'a mut LoadContext, ) -> BoxedFuture<'a, Result<(), anyhow::Error>> {
) -> BoxedFuture<'a, Result<Self::Asset, Self::Error>> {
Box::pin(async move { Box::pin(async move {
let mut bytes = Vec::new(); let buffer: Option<Buffer> =
reader.read_to_end(&mut bytes).await?; match load_context.path().extension().unwrap().to_str().unwrap() {
let buffer = syz::Buffer::from_encoded_data(&bytes).map(Buffer)?; "flac" | "mp3" | "wav" => {
Ok(buffer) syz::Buffer::from_encoded_data(bytes).map(Buffer).ok()
}
_ => None,
};
if let Some(buffer) = buffer {
load_context.set_default_asset(LoadedAsset::new(buffer));
}
Ok(())
}) })
} }
@ -383,7 +374,7 @@ fn change_panner_strategy(
check.push(entity); check.push(entity);
} }
} }
for entity in removed.read() { for entity in removed.iter() {
check.push(entity); check.push(entity);
} }
for entity in check.iter() { for entity in check.iter() {
@ -584,7 +575,7 @@ fn update_sound_playback_state(query: Query<&Sound>) {
} }
fn remove_sound(mut last_buffer: ResMut<LastAudio>, mut removed: RemovedComponents<Sound>) { fn remove_sound(mut last_buffer: ResMut<LastAudio>, mut removed: RemovedComponents<Sound>) {
for entity in removed.read() { for entity in removed.iter() {
last_buffer.remove(&entity); last_buffer.remove(&entity);
} }
} }
@ -732,7 +723,7 @@ impl Plugin for SynthizerPlugin {
}; };
context.enable_events().expect("Failed to enable events"); context.enable_events().expect("Failed to enable events");
let context = Context(context); let context = Context(context);
app.init_asset::<Buffer>() app.add_asset::<Buffer>()
.init_asset_loader::<BufferAssetLoader>() .init_asset_loader::<BufferAssetLoader>()
.register_type::<DistanceRef>() .register_type::<DistanceRef>()
.register_type::<DistanceMax>() .register_type::<DistanceMax>()
@ -749,15 +740,14 @@ impl Plugin for SynthizerPlugin {
.add_event::<SynthizerEvent>() .add_event::<SynthizerEvent>()
.add_systems( .add_systems(
PreUpdate, PreUpdate,
(sync_config, swap_buffers, change_panner_strategy) (sync_config, swap_buffers, change_panner_strategy).in_set(SynthizerSets::PreUpdate),
.in_set(SynthizerSets::PreUpdate),
) )
.add_systems( .add_systems(
PostUpdate, PostUpdate,
(add_sound_without_source, add_source_handle, add_generator) (add_sound_without_source, add_source_handle, add_generator)
.in_set(SynthizerSets::UpdateHandles), .in_set(SynthizerSets::UpdateHandles),
) )
.configure_sets( .configure_set(
PostUpdate, PostUpdate,
SynthizerSets::UpdateHandles.before(SynthizerSets::UpdateProperties), SynthizerSets::UpdateHandles.before(SynthizerSets::UpdateProperties),
) )
@ -771,7 +761,7 @@ impl Plugin for SynthizerPlugin {
.in_set(SynthizerSets::UpdateProperties) .in_set(SynthizerSets::UpdateProperties)
.after(TransformSystem::TransformPropagate), .after(TransformSystem::TransformPropagate),
) )
.configure_sets( .configure_set(
PostUpdate, PostUpdate,
SynthizerSets::UpdateProperties.before(SynthizerSets::UpdateState), SynthizerSets::UpdateProperties.before(SynthizerSets::UpdateState),
) )
@ -780,7 +770,7 @@ impl Plugin for SynthizerPlugin {
(update_source_playback_state, update_sound_playback_state) (update_source_playback_state, update_sound_playback_state)
.in_set(SynthizerSets::UpdateState), .in_set(SynthizerSets::UpdateState),
) )
.configure_sets( .configure_set(
PostUpdate, PostUpdate,
SynthizerSets::UpdateState.before(SynthizerSets::Last), SynthizerSets::UpdateState.before(SynthizerSets::Last),
) )