diff --git a/CHANGELOG.md b/CHANGELOG.md index 616deb65..5809d563 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - HashMap iterators now implement `size_hint` which should result in slightly better generation of code using those iterators. - Transparency of backgrounds is now set once in the toml file rather than once for every image. - Palette generation now takes into account every single background a toml definition rather than one at a time, you can now find it in the PALETTES constant rather than in every individual image. +- Sound frequency is no longer a crate feature, instead set when initialising the sound mixer. ### Fixed - Fixed the fast magnitude function in agb_fixnum. This is also used in fast_normalise. Previously only worked for positive (x, y). diff --git a/agb-sound-converter/Cargo.toml b/agb-sound-converter/Cargo.toml index 5d6f316d..caea2f60 100644 --- a/agb-sound-converter/Cargo.toml +++ b/agb-sound-converter/Cargo.toml @@ -18,10 +18,6 @@ debug = true [lib] proc-macro = true -[features] -freq18157 = [] -freq32768 = [] - [dependencies] hound = "3.5" syn = "1" diff --git a/agb-sound-converter/src/lib.rs b/agb-sound-converter/src/lib.rs index b04f280b..5cbc2446 100644 --- a/agb-sound-converter/src/lib.rs +++ b/agb-sound-converter/src/lib.rs @@ -6,15 +6,6 @@ use quote::{quote, ToTokens}; use std::path::Path; use syn::parse_macro_input; -#[cfg(all(not(feature = "freq18157"), not(feature = "freq32768")))] -const FREQUENCY: u32 = 10512; -#[cfg(feature = "freq18157")] -const FREQUENCY: u32 = 18157; -#[cfg(feature = "freq32768")] -const FREQUENCY: u32 = 32768; -#[cfg(all(feature = "freq18157", feature = "freq32768"))] -compile_error!("Must have at most one of freq18157 or freq32768 features enabled"); - use quote::TokenStreamExt; struct ByteString<'a>(&'a [u8]); impl ToTokens for ByteString<'_> { @@ -37,13 +28,6 @@ pub fn include_wav(input: TokenStream) -> TokenStream { let wav_reader = hound::WavReader::open(&path) .unwrap_or_else(|_| panic!("Failed to load file {}", include_path)); - assert_eq!( - wav_reader.spec().sample_rate, - FREQUENCY, - "agb currently only supports sample rate of {}Hz", - FREQUENCY - ); - let samples: Vec = samples_from_reader(wav_reader).collect(); let samples = ByteString(&samples); diff --git a/agb/Cargo.toml b/agb/Cargo.toml index 83afc851..29070813 100644 --- a/agb/Cargo.toml +++ b/agb/Cargo.toml @@ -17,8 +17,6 @@ debug = true [features] default = ["testing"] -freq18157 = ["agb_sound_converter/freq18157"] -freq32768 = ["agb_sound_converter/freq32768"] testing = [] [dependencies] @@ -34,7 +32,3 @@ rustc-hash = { version = "1", default-features = false } [package.metadata.docs.rs] default-target = "thumbv6m-none-eabi" targets = [] - -[[example]] -name = "mixer_32768" -required-features = ["freq32768"] \ No newline at end of file diff --git a/agb/examples/mixer_32768.rs b/agb/examples/mixer_32768.rs index b10bf8d3..8dd38120 100644 --- a/agb/examples/mixer_32768.rs +++ b/agb/examples/mixer_32768.rs @@ -7,7 +7,7 @@ use agb::{ Font, Priority, }, include_font, include_wav, - sound::mixer::SoundChannel, + sound::mixer::{Frequency, SoundChannel}, Gba, }; @@ -40,7 +40,7 @@ fn main(mut gba: Gba) -> ! { let mut timer = timer_controller.timer2; timer.set_enabled(true); - let mut mixer = gba.mixer.mixer(); + let mut mixer = gba.mixer.mixer(Frequency::Hz32768); mixer.enable(); let _interrupt = mixer.setup_interrupt_handler(); diff --git a/agb/examples/mixer_basic.rs b/agb/examples/mixer_basic.rs index 1419562b..e3fc76f9 100644 --- a/agb/examples/mixer_basic.rs +++ b/agb/examples/mixer_basic.rs @@ -3,7 +3,7 @@ use agb::fixnum::Num; use agb::input::{Button, ButtonController, Tri}; -use agb::sound::mixer::SoundChannel; +use agb::sound::mixer::{Frequency, SoundChannel}; use agb::{fixnum::num, include_wav, Gba}; // Music - "Dead Code" by Josh Woodward, free download at http://joshwoodward.com @@ -14,7 +14,7 @@ fn main(mut gba: Gba) -> ! { let mut input = ButtonController::new(); let vblank_provider = agb::interrupt::VBlank::get(); - let mut mixer = gba.mixer.mixer(); + let mut mixer = gba.mixer.mixer(Frequency::Hz10512); mixer.enable(); let channel = SoundChannel::new(DEAD_CODE); diff --git a/agb/examples/stereo_sound.rs b/agb/examples/stereo_sound.rs index ca293cf5..66dbcdee 100644 --- a/agb/examples/stereo_sound.rs +++ b/agb/examples/stereo_sound.rs @@ -7,7 +7,7 @@ use agb::{ Font, Priority, }, include_font, include_wav, - sound::mixer::SoundChannel, + sound::mixer::{Frequency, SoundChannel}, Gba, }; @@ -40,7 +40,7 @@ fn main(mut gba: Gba) -> ! { let mut timer = timer_controller.timer2; timer.set_enabled(true); - let mut mixer = gba.mixer.mixer(); + let mut mixer = gba.mixer.mixer(Frequency::Hz10512); mixer.enable(); let mut channel = SoundChannel::new(LET_IT_IN); diff --git a/agb/src/display/tiled/infinite_scrolled_map.rs b/agb/src/display/tiled/infinite_scrolled_map.rs index 773ff782..ed30997d 100644 --- a/agb/src/display/tiled/infinite_scrolled_map.rs +++ b/agb/src/display/tiled/infinite_scrolled_map.rs @@ -160,7 +160,7 @@ impl<'a> InfiniteScrolledMap<'a> { /// # ); /// # /// # let vblank = agb::interrupt::VBlank::get(); - /// # let mut mixer = gba.mixer.mixer(); + /// # let mut mixer = gba.mixer.mixer(agb::sound::mixer::Frequency::Hz10512); /// let start_position = agb::fixnum::Vector2D::new(10, 10); /// backdrop.init(&mut vram, start_position, &mut || { /// vblank.wait_for_vblank(); @@ -235,7 +235,7 @@ impl<'a> InfiniteScrolledMap<'a> { /// # ); /// # /// # let vblank = agb::interrupt::VBlank::get(); - /// # let mut mixer = gba.mixer.mixer(); + /// # let mut mixer = gba.mixer.mixer(agb::sound::mixer::Frequency::Hz10512); /// let start_position = agb::fixnum::Vector2D::new(10, 10); /// while backdrop.init_partial(&mut vram, start_position) == PartialUpdateStatus::Continue { /// vblank.wait_for_vblank(); diff --git a/agb/src/sound/mixer/mod.rs b/agb/src/sound/mixer/mod.rs index ac01dba7..64b82c46 100644 --- a/agb/src/sound/mixer/mod.rs +++ b/agb/src/sound/mixer/mod.rs @@ -14,17 +14,11 @@ //! //! # Concepts //! -//! The mixer runs at a fixed frequency which is determined at compile time by enabling -//! certain features within the crate. The following features are currently available: -//! -//! | Feature | Frequency | -//! |---------|-----------| -//! | none | 10512Hz | -//! | freq18157 | 18157Hz | -//! | freq32768[^32768Hz] | 32768Hz | +//! The mixer runs at a fixed frequency which is determined at initialisation time by +//! passing certain [`Frequency`] options. //! //! All wav files you use within your application / game must use this _exact_ frequency. -//! You will get a compile error if you use the incorrect frequency for your file. +//! If you don't use this frequency, the sound will play either too slowly or too quickly. //! //! The mixer can play both mono and stereo sounds, but only mono sound effects can have //! effects applied to them (such as changing the speed at which they play or the panning). @@ -38,12 +32,17 @@ //! ```rust,no_run //! # #![no_std] //! # #![no_main] +//! use agb::sound::mixer::Frequency; //! # fn foo(gba: &mut agb::Gba) { -//! let mut mixer = gba.mixer.mixer(); +//! let mut mixer = gba.mixer.mixer(Frequency::Hz10512); //! mixer.enable(); //! # } //! ``` //! +//! Pass a frequency option. This option must be used for the entire lifetime of the `mixer` +//! variable. If you want to change frequency, you will need to drop this one and create a new +//! one. +//! //! ## Doing the per-frame work //! //! Then, you have a choice of whether you want to use interrupts or do the buffer swapping @@ -55,9 +54,10 @@ //! ```rust,no_run //! # #![no_std] //! # #![no_main] +//! use agb::sound::mixer::Frequency; //! # fn foo(gba: &mut agb::Gba) { -//! # let mut mixer = gba.mixer.mixer(); -//! # let vblank = agb::interrupt::VBlank::get(); +//! let mut mixer = gba.mixer.mixer(Frequency::Hz10512); +//! let vblank = agb::interrupt::VBlank::get(); //! // Somewhere in your main loop: //! mixer.frame(); //! vblank.wait_for_vblank(); @@ -70,10 +70,13 @@ //! ```rust,no_run //! # #![no_std] //! # #![no_main] +//! use agb::sound::mixer::Frequency; //! # fn foo(gba: &mut agb::Gba) { -//! # let mut mixer = gba.mixer.mixer(); -//! # let vblank = agb::interrupt::VBlank::get(); +//! let mut mixer = gba.mixer.mixer(agb::sound::mixer::Frequency::Hz32768); +//! let vblank = agb::interrupt::VBlank::get(); //! // outside your main loop, close to initialisation +//! // you must assign this to a variable (not to _ or ignored) or rust will immediately drop it +//! // and prevent the interrupt handler from firing. //! let _mixer_interrupt = mixer.setup_interrupt_handler(); //! //! // inside your main loop @@ -99,7 +102,7 @@ //! # #![no_std] //! # #![no_main] //! # fn foo(gba: &mut agb::Gba) { -//! # let mut mixer = gba.mixer.mixer(); +//! # let mut mixer = gba.mixer.mixer(agb::sound::mixer::Frequency::Hz10512); //! # let vblank = agb::interrupt::VBlank::get(); //! # use agb::{*, sound::mixer::*}; //! // Outside your main function in global scope: @@ -116,9 +119,6 @@ //! //! Once you have run [`play_sound`](Mixer::play_sound), the mixer will play that sound until //! it has finished. -//! -//! [^32768Hz]: You must use interrupts when using 32768Hz - mod hw; mod sw_mixer; @@ -138,8 +138,8 @@ impl MixerController { } /// Get a [`Mixer`] in order to start producing sounds. - pub fn mixer(&mut self) -> Mixer { - Mixer::new() + pub fn mixer(&mut self, frequency: Frequency) -> Mixer { + Mixer::new(frequency) } } @@ -149,6 +149,43 @@ enum SoundPriority { Low, } +/// The supported frequencies within AGB. These are chosen to work well with +/// the hardware. Note that the higher the frequency, the better the quality of +/// the sound but the more CPU time sound mixing will take. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[non_exhaustive] +pub enum Frequency { + /// 10512Hz + Hz10512, + /// 18157Hz + Hz18157, + /// 32768Hz - note that this option requires interrupts for buffer swapping + Hz32768, +} + +// list here: http://deku.gbadev.org/program/sound1.html +impl Frequency { + pub(crate) fn frequency(self) -> i32 { + use Frequency::*; + + match self { + Hz10512 => 10512, + Hz18157 => 18157, + Hz32768 => 32768, + } + } + + pub(crate) fn buffer_size(self) -> usize { + use Frequency::*; + + match self { + Hz10512 => 176, + Hz18157 => 304, + Hz32768 => 560, + } + } +} + /// Describes one sound which should be playing. This could be a sound effect or /// the background music. Use the factory methods on this to modify how it is played. /// @@ -185,7 +222,7 @@ enum SoundPriority { /// /// // somewhere in code /// # fn foo(gba: &mut Gba) { -/// # let mut mixer = gba.mixer.mixer(); +/// # let mut mixer = gba.mixer.mixer(agb::sound::mixer::Frequency::Hz10512); /// let mut bgm = SoundChannel::new_high_priority(MY_BGM); /// bgm.stereo().should_loop(); /// let _ = mixer.play_sound(bgm); @@ -204,7 +241,7 @@ enum SoundPriority { /// /// // somewhere in code /// # fn foo(gba: &mut Gba) { -/// # let mut mixer = gba.mixer.mixer(); +/// # let mut mixer = gba.mixer.mixer(agb::sound::mixer::Frequency::Hz10512); /// let jump_sound = SoundChannel::new(JUMP_SOUND); /// let _ = mixer.play_sound(jump_sound); /// # } @@ -241,7 +278,7 @@ impl SoundChannel { /// # use agb::sound::mixer::*; /// # use agb::*; /// # fn foo(gba: &mut Gba) { - /// # let mut mixer = gba.mixer.mixer(); + /// # let mut mixer = gba.mixer.mixer(agb::sound::mixer::Frequency::Hz10512); /// // in global scope: /// const JUMP_SOUND: &[u8] = include_wav!("examples/sfx/jump.wav"); /// @@ -283,7 +320,7 @@ impl SoundChannel { /// # use agb::sound::mixer::*; /// # use agb::*; /// # fn foo(gba: &mut Gba) { - /// # let mut mixer = gba.mixer.mixer(); + /// # let mut mixer = gba.mixer.mixer(agb::sound::mixer::Frequency::Hz10512); /// // in global scope: /// const MY_BGM: &[u8] = include_wav!("examples/sfx/my_bgm.wav"); /// diff --git a/agb/src/sound/mixer/sw_mixer.rs b/agb/src/sound/mixer/sw_mixer.rs index 80b5b139..44c17c4f 100644 --- a/agb/src/sound/mixer/sw_mixer.rs +++ b/agb/src/sound/mixer/sw_mixer.rs @@ -1,12 +1,14 @@ use core::cell::RefCell; -use core::intrinsics::transmute; +use alloc::boxed::Box; +use alloc::vec::Vec; use bare_metal::{CriticalSection, Mutex}; -use super::hw; use super::hw::LeftOrRight; +use super::{hw, Frequency}; use super::{SoundChannel, SoundPriority}; +use crate::InternalAllocator; use crate::{ fixnum::Num, interrupt::free, @@ -46,7 +48,7 @@ extern "C" { /// # use agb::sound::mixer::*; /// # use agb::*; /// # fn foo(gba: &mut Gba) { -/// let mut mixer = gba.mixer.mixer(); +/// let mut mixer = gba.mixer.mixer(Frequency::Hz10512); /// # } /// ``` /// @@ -58,13 +60,13 @@ extern "C" { /// # use agb::sound::mixer::*; /// # use agb::*; /// # fn foo(gba: &mut Gba) { -/// # let mut mixer = gba.mixer.mixer(); +/// # let mut mixer = gba.mixer.mixer(agb::sound::mixer::Frequency::Hz10512); /// # let vblank = agb::interrupt::VBlank::get(); /// // Outside your main function in global scope: /// const MY_CRAZY_SOUND: &[u8] = include_wav!("examples/sfx/jump.wav"); /// /// // in your main function: -/// let mut mixer = gba.mixer.mixer(); +/// let mut mixer = gba.mixer.mixer(Frequency::Hz10512); /// let mut channel = SoundChannel::new(MY_CRAZY_SOUND); /// channel.stereo(); /// let _ = mixer.play_sound(channel); @@ -80,6 +82,7 @@ pub struct Mixer { buffer: MixerBuffer, channels: [Option; 8], indices: [i32; 8], + frequency: Frequency, timer: Timer, } @@ -96,7 +99,7 @@ pub struct Mixer { /// # use agb::sound::mixer::*; /// # use agb::*; /// # fn foo(gba: &mut Gba) { -/// # let mut mixer = gba.mixer.mixer(); +/// # let mut mixer = gba.mixer.mixer(agb::sound::mixer::Frequency::Hz10512); /// # const MY_BGM: &[u8] = include_wav!("examples/sfx/my_bgm.wav"); /// let mut channel = SoundChannel::new_high_priority(MY_BGM); /// let bgm_channel_id = mixer.play_sound(channel).unwrap(); // will always be Some if high priority @@ -108,9 +111,10 @@ pub struct Mixer { pub struct ChannelId(usize, i32); impl Mixer { - pub(super) fn new() -> Self { + pub(super) fn new(frequency: Frequency) -> Self { Self { - buffer: MixerBuffer::new(), + frequency, + buffer: MixerBuffer::new(frequency), channels: Default::default(), indices: Default::default(), @@ -123,7 +127,7 @@ impl Mixer { /// You must call this method in order to start playing sound. You can do as much set up before /// this as you like, but you will not get any sound out of the console until this method is called. pub fn enable(&mut self) { - hw::set_timer_counter_for_frequency_and_enable(&mut self.timer, constants::SOUND_FREQUENCY); + hw::set_timer_counter_for_frequency_and_enable(&mut self.timer, self.frequency.frequency()); hw::set_sound_control_register_for_mixer(); } @@ -138,7 +142,7 @@ impl Mixer { /// # use agb::sound::mixer::*; /// # use agb::*; /// # fn foo(gba: &mut Gba) { - /// # let mut mixer = gba.mixer.mixer(); + /// # let mut mixer = gba.mixer.mixer(agb::sound::mixer::Frequency::Hz10512); /// # let vblank = agb::interrupt::VBlank::get(); /// loop { /// mixer.frame(); @@ -167,7 +171,7 @@ impl Mixer { /// # use agb::sound::mixer::*; /// # use agb::*; /// # fn foo(gba: &mut Gba) { - /// # let mut mixer = gba.mixer.mixer(); + /// # let mut mixer = gba.mixer.mixer(agb::sound::mixer::Frequency::Hz10512); /// # let vblank = agb::interrupt::VBlank::get(); /// // you must set this to a named variable to ensure that the scope is long enough /// let _mixer_interrupt = mixer.setup_interrupt_handler(); @@ -184,7 +188,7 @@ impl Mixer { .set_cascade(true) .set_divider(Divider::Divider1) .set_interrupt(true) - .set_overflow_amount(constants::SOUND_BUFFER_SIZE as u16) + .set_overflow_amount(self.frequency.buffer_size() as u16) .set_enabled(true); add_interrupt_handler(timer1.interrupt(), move |cs| self.buffer.swap(cs)) @@ -205,7 +209,7 @@ impl Mixer { /// # use agb::sound::mixer::*; /// # use agb::*; /// # fn foo(gba: &mut Gba) { - /// # let mut mixer = gba.mixer.mixer(); + /// # let mut mixer = gba.mixer.mixer(agb::sound::mixer::Frequency::Hz10512); /// # let vblank = agb::interrupt::VBlank::get(); /// loop { /// mixer.frame(); @@ -244,7 +248,7 @@ impl Mixer { /// # use agb::sound::mixer::*; /// # use agb::*; /// # fn foo(gba: &mut Gba) { - /// # let mut mixer = gba.mixer.mixer(); + /// # let mut mixer = gba.mixer.mixer(agb::sound::mixer::Frequency::Hz10512); /// # const MY_BGM: &[u8] = include_wav!("examples/sfx/my_bgm.wav"); /// let mut channel = SoundChannel::new_high_priority(MY_BGM); /// let bgm_channel_id = mixer.play_sound(channel).unwrap(); // will always be Some if high priority @@ -293,7 +297,7 @@ impl Mixer { /// # use agb::sound::mixer::*; /// # use agb::*; /// # fn foo(gba: &mut Gba) { - /// # let mut mixer = gba.mixer.mixer(); + /// # let mut mixer = gba.mixer.mixer(agb::sound::mixer::Frequency::Hz10512); /// # const MY_BGM: &[u8] = include_wav!("examples/sfx/my_bgm.wav"); /// let mut channel = SoundChannel::new_high_priority(MY_BGM); /// let bgm_channel_id = mixer.play_sound(channel).unwrap(); // will always be Some if high priority @@ -313,47 +317,32 @@ impl Mixer { } } -// These work perfectly with swapping the buffers every vblank -// list here: http://deku.gbadev.org/program/sound1.html -#[cfg(all(not(feature = "freq18157"), not(feature = "freq32768")))] -mod constants { - pub const SOUND_FREQUENCY: i32 = 10512; - pub const SOUND_BUFFER_SIZE: usize = 176; -} - -#[cfg(feature = "freq18157")] -mod constants { - pub const SOUND_FREQUENCY: i32 = 18157; - pub const SOUND_BUFFER_SIZE: usize = 304; -} - -#[cfg(feature = "freq32768")] -mod constants { - pub const SOUND_FREQUENCY: i32 = 32768; - pub const SOUND_BUFFER_SIZE: usize = 560; -} - -fn set_asm_buffer_size() { +fn set_asm_buffer_size(frequency: Frequency) { extern "C" { static mut agb_rs__buffer_size: usize; } unsafe { - agb_rs__buffer_size = constants::SOUND_BUFFER_SIZE; + agb_rs__buffer_size = frequency.buffer_size(); } } -#[repr(C, align(4))] -struct SoundBuffer([i8; constants::SOUND_BUFFER_SIZE * 2]); +struct SoundBuffer(Box<[i8], InternalAllocator>); -impl Default for SoundBuffer { - fn default() -> Self { - Self([0; constants::SOUND_BUFFER_SIZE * 2]) +impl SoundBuffer { + fn new(frequency: Frequency) -> Self { + let my_size = frequency.buffer_size() * 2; + let mut v = Vec::with_capacity_in(my_size, InternalAllocator); + v.resize(my_size, 0); + + SoundBuffer(v.into_boxed_slice()) } } struct MixerBuffer { buffers: [SoundBuffer; 3], + working_buffer: Box<[Num], InternalAllocator>, + frequency: Frequency, state: Mutex>, } @@ -391,16 +380,26 @@ impl MixerBufferState { } impl MixerBuffer { - fn new() -> Self { - set_asm_buffer_size(); + fn new(frequency: Frequency) -> Self { + let mut working_buffer = + Vec::with_capacity_in(frequency.buffer_size() * 2, InternalAllocator); + working_buffer.resize(frequency.buffer_size() * 2, 0.into()); MixerBuffer { - buffers: Default::default(), + buffers: [ + SoundBuffer::new(frequency), + SoundBuffer::new(frequency), + SoundBuffer::new(frequency), + ], + + working_buffer: working_buffer.into_boxed_slice(), state: Mutex::new(RefCell::new(MixerBufferState { active_buffer: 0, playing_buffer: 0, })), + + frequency, } } @@ -413,15 +412,16 @@ impl MixerBuffer { let (left_buffer, right_buffer) = self.buffers[buffer] .0 - .split_at(constants::SOUND_BUFFER_SIZE); + .split_at(self.frequency.buffer_size()); hw::enable_dma_for_sound(left_buffer, LeftOrRight::Left); hw::enable_dma_for_sound(right_buffer, LeftOrRight::Right); } fn write_channels<'a>(&mut self, channels: impl Iterator) { - let mut buffer: [Num; constants::SOUND_BUFFER_SIZE * 2] = - unsafe { transmute([0i16; constants::SOUND_BUFFER_SIZE * 2]) }; + set_asm_buffer_size(self.frequency); + + self.working_buffer.fill(0.into()); for channel in channels { if channel.is_done { @@ -434,7 +434,7 @@ impl MixerBuffer { channel.playback_speed }; - if (channel.pos + playback_speed * constants::SOUND_BUFFER_SIZE).floor() + if (channel.pos + playback_speed * self.frequency.buffer_size()).floor() >= channel.data.len() { // TODO: This should probably play what's left rather than skip the last bit @@ -450,7 +450,7 @@ impl MixerBuffer { unsafe { agb_rs__mixer_add_stereo( channel.data.as_ptr().add(channel.pos.floor()), - buffer.as_mut_ptr(), + self.working_buffer.as_mut_ptr(), channel.volume, ); } @@ -461,7 +461,7 @@ impl MixerBuffer { unsafe { agb_rs__mixer_add( channel.data.as_ptr().add(channel.pos.floor()), - buffer.as_mut_ptr(), + self.working_buffer.as_mut_ptr(), playback_speed, left_amount, right_amount, @@ -469,7 +469,7 @@ impl MixerBuffer { } } - channel.pos += playback_speed * constants::SOUND_BUFFER_SIZE; + channel.pos += playback_speed * self.frequency.buffer_size(); } let write_buffer_index = free(|cs| self.state.borrow(cs).borrow_mut().active_advanced()); @@ -477,7 +477,7 @@ impl MixerBuffer { let write_buffer = &mut self.buffers[write_buffer_index].0; unsafe { - agb_rs__mixer_collapse(write_buffer.as_mut_ptr(), buffer.as_ptr()); + agb_rs__mixer_collapse(write_buffer.as_mut_ptr(), self.working_buffer.as_ptr()); } } } diff --git a/examples/hyperspace-roll/Cargo.toml b/examples/hyperspace-roll/Cargo.toml index 76c3f4bc..317e2525 100644 --- a/examples/hyperspace-roll/Cargo.toml +++ b/examples/hyperspace-roll/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -agb = { version = "0.11.1", path = "../../agb", features = ["freq32768"] } +agb = { version = "0.11.1", path = "../../agb" } bare-metal = "1" [profile.dev] diff --git a/examples/hyperspace-roll/src/main.rs b/examples/hyperspace-roll/src/main.rs index 9e1f4823..cd61df84 100644 --- a/examples/hyperspace-roll/src/main.rs +++ b/examples/hyperspace-roll/src/main.rs @@ -10,11 +10,11 @@ // which won't be a particularly clear error message. #![no_main] -use agb::display; use agb::display::object::ObjectController; use agb::display::tiled::{TiledMap, VRamManager}; use agb::display::Priority; use agb::interrupt::VBlank; +use agb::{display, sound::mixer::Frequency}; extern crate alloc; use alloc::vec; @@ -138,7 +138,7 @@ fn main(mut gba: agb::Gba) -> ! { let mut star_background = StarBackground::new(&mut background0, &mut background1, &mut vram); star_background.commit(&mut vram); - let mut mixer = gba.mixer.mixer(); + let mut mixer = gba.mixer.mixer(Frequency::Hz32768); mixer.enable(); let _interrupt_handler = mixer.setup_interrupt_handler(); diff --git a/examples/the-hat-chooses-the-wizard/src/main.rs b/examples/the-hat-chooses-the-wizard/src/main.rs index e5592fa3..b69c1a48 100644 --- a/examples/the-hat-chooses-the-wizard/src/main.rs +++ b/examples/the-hat-chooses-the-wizard/src/main.rs @@ -17,6 +17,7 @@ use agb::{ }, fixnum::{FixedNum, Vector2D}, input::{self, Button, ButtonController}, + sound::mixer::Frequency, }; use alloc::boxed::Box; @@ -820,7 +821,7 @@ pub fn main(mut agb: agb::Gba) -> ! { vram.set_background_palettes(tile_sheet::PALETTES); let object = agb.display.object.get(); - let mut mixer = agb.mixer.mixer(); + let mut mixer = agb.mixer.mixer(Frequency::Hz10512); mixer.enable(); let mut music_box = sfx::MusicBox::new(); diff --git a/examples/the-purple-night/Cargo.toml b/examples/the-purple-night/Cargo.toml index 33f2e83d..eeac7e0f 100644 --- a/examples/the-purple-night/Cargo.toml +++ b/examples/the-purple-night/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -agb = { path = "../../agb", version = "0.11.1", features = ["freq18157"]} +agb = { path = "../../agb", version = "0.11.1" } generational-arena = { version = "0.2", default-features = false } [build-dependencies] diff --git a/examples/the-purple-night/src/main.rs b/examples/the-purple-night/src/main.rs index ce906f9a..922b4e3a 100644 --- a/examples/the-purple-night/src/main.rs +++ b/examples/the-purple-night/src/main.rs @@ -22,6 +22,7 @@ use agb::{ input::{Button, ButtonController, Tri}, interrupt::VBlank, rng, + sound::mixer::Frequency, }; use generational_arena::Arena; use sfx::Sfx; @@ -2205,7 +2206,7 @@ fn game_with_level(gba: &mut agb::Gba) { let vblank = agb::interrupt::VBlank::get(); vblank.wait_for_vblank(); - let mut mixer = gba.mixer.mixer(); + let mut mixer = gba.mixer.mixer(Frequency::Hz18157); mixer.enable(); let mut sfx = sfx::Sfx::new(&mut mixer);