mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
Added Pitch as an alternative sound source (#9225)
# Objective My attempt at implementing #7515 ## Solution Added struct `Pitch` and implemented on it `Source` trait. ## Changelog ### Added - File pitch.rs to bevy_audio crate - Struct `Pitch` and type aliases for `AudioSourceBundle<Pitch>` and `SpatialAudioSourceBundle<Pitch>` - New example showing how to use `PitchBundle` ### Changed - `AudioPlugin` now adds system for `Pitch` audio --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
parent
a88b9fc6a9
commit
fb9c5a6cbb
5 changed files with 110 additions and 2 deletions
10
Cargo.toml
10
Cargo.toml
|
@ -1043,6 +1043,16 @@ description = "Shows how to play spatial audio, and moving the emitter in 3D"
|
|||
category = "Audio"
|
||||
wasm = true
|
||||
|
||||
[[example]]
|
||||
name = "pitch"
|
||||
path = "examples/audio/pitch.rs"
|
||||
|
||||
[package.metadata.example.pitch]
|
||||
name = "Pitch"
|
||||
description = "Shows how to directly play a simple pitch"
|
||||
category = "Audio"
|
||||
wasm = true
|
||||
|
||||
# Diagnostics
|
||||
[[example]]
|
||||
name = "log_diagnostics"
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
mod audio;
|
||||
mod audio_output;
|
||||
mod audio_source;
|
||||
mod pitch;
|
||||
mod sinks;
|
||||
|
||||
#[allow(missing_docs)]
|
||||
|
@ -34,13 +35,14 @@ pub mod prelude {
|
|||
#[doc(hidden)]
|
||||
pub use crate::{
|
||||
AudioBundle, AudioSink, AudioSinkPlayback, AudioSource, AudioSourceBundle, Decodable,
|
||||
GlobalVolume, PlaybackSettings, SpatialAudioBundle, SpatialAudioSink,
|
||||
SpatialAudioSourceBundle, SpatialSettings,
|
||||
GlobalVolume, Pitch, PitchBundle, PlaybackSettings, SpatialAudioBundle, SpatialAudioSink,
|
||||
SpatialAudioSourceBundle, SpatialPitchBundle, SpatialSettings,
|
||||
};
|
||||
}
|
||||
|
||||
pub use audio::*;
|
||||
pub use audio_source::*;
|
||||
pub use pitch::*;
|
||||
|
||||
pub use rodio::cpal::Sample as CpalSample;
|
||||
pub use rodio::source::Source;
|
||||
|
@ -77,6 +79,8 @@ impl Plugin for AudioPlugin {
|
|||
app.add_audio_source::<AudioSource>();
|
||||
app.init_asset_loader::<AudioLoader>();
|
||||
}
|
||||
|
||||
app.add_audio_source::<Pitch>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
38
crates/bevy_audio/src/pitch.rs
Normal file
38
crates/bevy_audio/src/pitch.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
use crate::{AudioSourceBundle, Decodable, SpatialAudioSourceBundle};
|
||||
use bevy_reflect::{TypePath, TypeUuid};
|
||||
use rodio::{source::SineWave, source::TakeDuration, Source};
|
||||
|
||||
/// A source of sine wave sound
|
||||
#[derive(Debug, Clone, TypeUuid, TypePath)]
|
||||
#[uuid = "cbc63be3-b0b9-4d2c-a03c-88b58f1a19ef"]
|
||||
pub struct Pitch {
|
||||
/// Frequency at which sound will be played
|
||||
pub frequency: f32,
|
||||
/// Duration for which sound will be played
|
||||
pub duration: std::time::Duration,
|
||||
}
|
||||
|
||||
impl Pitch {
|
||||
/// Creates a new note
|
||||
pub fn new(frequency: f32, duration: std::time::Duration) -> Self {
|
||||
Pitch {
|
||||
frequency,
|
||||
duration,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for Pitch {
|
||||
type DecoderItem = <SineWave as Iterator>::Item;
|
||||
type Decoder = TakeDuration<SineWave>;
|
||||
|
||||
fn decoder(&self) -> Self::Decoder {
|
||||
SineWave::new(self.frequency).take_duration(self.duration)
|
||||
}
|
||||
}
|
||||
|
||||
/// Bundle for playing a bevy note sound
|
||||
pub type PitchBundle = AudioSourceBundle<Pitch>;
|
||||
|
||||
/// Bundle for playing a bevy note sound with a 3D position
|
||||
pub type SpatialPitchBundle = SpatialAudioSourceBundle<Pitch>;
|
|
@ -195,6 +195,7 @@ Example | Description
|
|||
[Audio](../examples/audio/audio.rs) | Shows how to load and play an audio file
|
||||
[Audio Control](../examples/audio/audio_control.rs) | Shows how to load and play an audio file, and control how it's played
|
||||
[Decodable](../examples/audio/decodable.rs) | Shows how to create and register a custom audio source by implementing the `Decodable` type.
|
||||
[Pitch](../examples/audio/pitch.rs) | Shows how to directly play a simple pitch
|
||||
[Spatial Audio 2D](../examples/audio/spatial_audio_2d.rs) | Shows how to play spatial audio, and moving the emitter in 2D
|
||||
[Spatial Audio 3D](../examples/audio/spatial_audio_3d.rs) | Shows how to play spatial audio, and moving the emitter in 3D
|
||||
|
||||
|
|
55
examples/audio/pitch.rs
Normal file
55
examples/audio/pitch.rs
Normal file
|
@ -0,0 +1,55 @@
|
|||
//! This example illustrates how to play a single-frequency sound (aka a pitch)
|
||||
|
||||
use bevy::prelude::*;
|
||||
use std::time::Duration;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_event::<PlayPitch>()
|
||||
.add_systems(Startup, setup)
|
||||
.add_systems(Update, (play_pitch, keyboard_input_system))
|
||||
.run();
|
||||
}
|
||||
|
||||
#[derive(Event, Default)]
|
||||
struct PlayPitch;
|
||||
|
||||
#[derive(Resource)]
|
||||
struct PitchFrequency(f32);
|
||||
|
||||
fn setup(mut commands: Commands) {
|
||||
commands.insert_resource(PitchFrequency(220.0));
|
||||
}
|
||||
|
||||
fn play_pitch(
|
||||
mut pitch_assets: ResMut<Assets<Pitch>>,
|
||||
frequency: Res<PitchFrequency>,
|
||||
mut events: EventReader<PlayPitch>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
for _ in events.iter() {
|
||||
info!("playing pitch with frequency: {}", frequency.0);
|
||||
commands.spawn(PitchBundle {
|
||||
source: pitch_assets.add(Pitch::new(frequency.0, Duration::new(1, 0))),
|
||||
settings: PlaybackSettings::DESPAWN,
|
||||
});
|
||||
info!("number of pitch assets: {}", pitch_assets.len());
|
||||
}
|
||||
}
|
||||
|
||||
fn keyboard_input_system(
|
||||
keyboard_input: Res<Input<KeyCode>>,
|
||||
mut frequency: ResMut<PitchFrequency>,
|
||||
mut events: EventWriter<PlayPitch>,
|
||||
) {
|
||||
if keyboard_input.just_pressed(KeyCode::Up) {
|
||||
frequency.0 *= 2.0f32.powf(1.0 / 12.0);
|
||||
}
|
||||
if keyboard_input.just_pressed(KeyCode::Down) {
|
||||
frequency.0 /= 2.0f32.powf(1.0 / 12.0);
|
||||
}
|
||||
if keyboard_input.just_pressed(KeyCode::Space) {
|
||||
events.send(PlayPitch);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue