Coder Social home page Coder Social logo

iced_audio's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iced_audio's Issues

ab_glyph_rasterizer-0.1.8 broke causing index out of bounds

In the stacktrace, at raster.rs 149:23, index length expects 4 but recieves 6

$ cargo run Compiling simple v0.1.0 (/Users/[USER]/DEV/iced_audio/examples/simple) Finished dev [unoptimized + debuginfo] target(s) in 1.82s Running /Users/[USER]/DEV/iced_audio/target/debug/simple2024-03-22 08:46:28.932 simple[78551:2307520] CAMetalLayer ignoring invalid setDrawableSize width=4294967295.000000 height=4294967295.000000 thread 'main' panicked at /Users/[USER]/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ab_glyph_rasterizer-0.1.8/src/raster.rs:149:23: index out of bounds: the len is 4 but the index is 13 note: run withRUST_BACKTRACE=1 environment variable to display a backtrace

How do you set a knob's value so that it does not "snap back"?

I have a VST parameter, in this case, volume, that I have interacting with a knob::State. I would like for the knob to be able to set the parameter, and for when the parameter is set by a VST host, that the knob change to reflect it. (ex: If I have an automation curve in Ableton that changes my volume parameter, I would like for the volume knob to rotate with it, and if I rotate the knob in GUI, I would like to have the parameter change to reflect that). There are a few problems I have encountered:

I have manage to almost achieve this goal. Specifically, I can

  • Turn the knob in the GUI and have the parameter change to reflect it.
  • Change the parameter via the VST host and have the knob rotate. I do this by altering knob.normal_param.value to the value I want.

However, when I click on the knob, the knob ends up "snapping" back to the previous spot it was since interacting with it in the GUI. (For example, if you lower the volume via the host, then click the knob in the GUI, the knob will "snap back" to its prior value). I think this is due to the fact that knob::State has an internal field continuous_normal, which looks like it tracks what the "real" position of the knob was. Hence, when the knob gets interacted with, this overwrites the previous value of knob.normal_param.value, causing the snapping behavior. It seems like this makes it impossible to actually keep a knob set via the normal_param.value field, since it will just snap upon interaction.

Thus, my question: How do I set the knob so that it does not do this snapping behavior?

Also, I've included some of the relevant code below:

// Messages for iced
pub enum Message {
    MasterVolume(Normal),
    ForceRedraw,
}

// My GUI struct
pub struct UIFrontEnd {
    // My knob in the GUI
    master_vol_knob: knob::State,
    // The actual parameters that the VST host sets. This is shared with the 
    // host thread. All that is relevant is that it contains a field called 
    // volume that is an AtomicFloat.
    params: std::sync::Arc<RawParameters>,
}

impl Application for UIFrontEnd {
    type Message = Message;

    fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
        match message {
            Message::MasterVolume(normal) => {
                // This is meant to update the parameter when the GUI knob is
                // changed. However, `normal` ends up being the value of whatever
                // the knob was since the last time it was interacted with in the 
                // GUI, which causes the volume to "snap back" to the wrong value
                self.params.volume.set(normal.as_f32());
            }
            // I end up sending this message via a Subscription every few
            // miliseconds. This is used to make the GUI knob update when
            // the VST host sets the parameter.
            Message::ForceRedraw => {
                self.master_vol_knob.normal_param.value = Normal::new(self.params.volume.get());
            }
        }

        Command::none()
    }

    fn view(&mut self) -> iced::Element<'_, Self::Message> {
        /// The knob widget displayed on the GUI. It sends Message::MasterVolume messages
        /// when interacted with.
        let master_vol_widget = Knob::new(&mut self.master_vol_knob, Message::MasterVolume);

        let content: Element<_> = Column::new().push(master_vol_widget).into();
        Container::new(content).into()
    }

    // This subscription is used to send ForceRedraw messages, which is just used
    // so that iced redraws the GUI.
    fn subscription(
        &self,
        _window_subs: &mut WindowSubs<Self::Message>,
    ) -> Subscription<Self::Message> {
        iced_futures::time::every(Duration::from_millis(33)).map(|_| Message::ForceRedraw)
    }
}

TL;DR: How do you set a knob to a different value so that when the user interacts with it, the knob does not go back to its previous value?

Broken on iced 0.3

The example in the readme is broken on iced 0.3 (0.2 works fine).

error[E0277]: the trait bound `iced_native::element::Element<'_, _, iced_graphics::renderer::Renderer<iced_wgpu::backend::Backend>>: From<iced_audio::native::HSlider<'_, Message, iced_graphics::renderer::Renderer<_>>>` is not satisfied
   --> src/gui.rs:136:14
    |
136 |             .push(h_slider_widget)
    |              ^^^^ the trait `From<iced_audio::native::HSlider<'_, Message, iced_graphics::renderer::Renderer<_>>>` is not implemented for `iced_native::element::Element<'_, _, iced_graphics::renderer::Renderer<iced_wgpu::backend::Backend>>`
    |
    = help: the following implementations were found:
              <iced_native::element::Element<'a, Message, Renderer> as From<Image>>
              <iced_native::element::Element<'a, Message, Renderer> as From<Svg>>
              <iced_native::element::Element<'a, Message, Renderer> as From<Viewer<'a>>>
              <iced_native::element::Element<'a, Message, Renderer> as From<iced::Space>>
            and 14 others
    = note: required because of the requirements on the impl of `Into<iced_native::element::Element<'_, _, iced_graphics::renderer::Renderer<iced_wgpu::backend::Backend>>>` for `iced_audio::native::HSlider<'_, Message, iced_graphics::renderer::Renderer<_>>`

etc. for all widgets.

(Thanks for this excellent selection of widgets!)

Implement an AudioViewer widget

An AudioViewer widget would be pretty helpful for audio software. It should:

  • Render a temporal waveform (a frequency one would be great but first we need to compute a DFT in some way)
  • Allow to select a portion of the rendered waveform through some kind of selectors and save the samples as WAV
  • Implement a slider to move over it

Official community crate

Hey @BillyDM!

I've been thinking about ways to start gathering a community around iced together and I was wondering if you would like to join the iced-rs organization, transfer this repository there, and kind of make it the "official, community-driven widget crate for audio". I willl move the main repository there too eventually, so I believe it could help with visibility and bring new contributors.

See this Zulip thread for a bit of additional context.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.