Giter VIP home page Giter VIP logo

ambisonic's People

Contributors

bjadamson avatar mbillingr avatar ocornoc avatar

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

Watchers

 avatar  avatar  avatar  avatar

ambisonic's Issues

Playback bug when using z-coordinate

Distance calculation is wrong in Bweights::from_position for any z != 0:

let dist = (pos[0] * pos[0] + pos[1] * pos[1] + pos[1] * pos[2]).sqrt()
                                                    ^ should be 2

Questions about loading an mp3/wav from rodio

Hello there, thanks for making this project! I went about trying to figure out how to an mp3 I loaded using the rodio library, and wanted to share what I found and discuss with you what you think. I hope that is ok!

First my use case is for a game I am making, whenever an NPC is moving I want to play a walking/running/slithering/buzzing/etc... sound at their 3d location. Before finding your library, I got this working using rodio, but my plan was to have your library help me with the 3d part of it. Without the 3d part the game doesn't feel as immersive.

My code is setup to hold a buffer of the data so I can create a sink when I want to play it, or pause it when the NPC stops moving.

I tried copy/pasting the code from the ambisonic readme and swapping the source to the source containing my mp3 file, but I got an error about a type-mismatch:
image

To work around this I figured out this adaptor code:

/// Since rodio requires everything to be Send + Sync, the data is wrapped with Arc so only one copy
/// of the data is in memory at a time per-sound.
#[derive(Default)]
pub struct Sound(Arc<Vec<u8>>);
impl AsRef<[u8]> for Sound {
    fn as_ref(&self) -> &[u8] {
        &self.0
    }
}

impl Sound {
    pub fn cursor(self: &Self) -> Cursor<Sound> {
        Cursor::new(Sound(self.0.clone()))
    }
}

This wrapper type wraps my custom buffer:

struct Wrapper(ambisonic::rodio::Decoder<Cursor<Sound>>);

impl Iterator for Wrapper {
    type Item = f32;

    #[inline]
    fn next(&mut self) -> Option<f32> {
        self.0.next().map(|v| v as f32) // v is type i16, is mapping the i16 value to f32 valid?
    }
}

impl ambisonic::rodio::Source for Wrapper {
    #[inline]
    fn current_frame_len(&self) -> Option<usize> {
        self.0.current_frame_len()
    }

    #[inline]
    fn channels(&self) -> u16 {
        self.0.channels()
    }

    #[inline]
    fn sample_rate(&self) -> u32 {
        self.0.sample_rate()
    }

    #[inline]
    fn total_duration(&self) -> Option<Duration> {
        self.0.total_duration()
    }
}

Also I needed to wrap the source:

let source = ambisonic::rodio::Decoder::new(cursor).unwrap();
let source = Wrapper(source); // wrap
let mut sound = scene.play_at(source, pos);

This Wrapper gets the code to compile and executing it works, the mp3 sound plays left-to-right in my headphones just like the sine wave code from the readme.

  1. All this boilerplate boils down to implementing Iterator for the type passed into play_at() because play_at() expects the input value to implement it for f32. Can ambisonic be changed to not care, or is f32 important here? Is mapping the i16 value to f32 valid?
  2. Since I was already using rodio in my project, I kept running into conflicts. Is it possible to disable exposing the rodio version used by ambisonic internally? This way I can keep using rodio from my cargo.toml and ambisonic can use the version it wants internally?

I'm super impressed that with such a small change ambisonic was able to work with the mp3 file, congrats on building something so cool (:

Sounds on the right seem centered

ambisonic = "0.4.1"

use ambisonic::{AmbisonicBuilder, HrtfConfig, PlaybackConfiguration};

pub fn test() {
    let mut position = [50.0, -2.0, 0.0];
    let velocity = [-0.1, 0.0, 0.0];

    let config = PlaybackConfiguration::Hrtf(HrtfConfig::default());
    let scene = AmbisonicBuilder::default().with_config(config).build();
    let source = ambisonic::rodio::source::SineWave::new(440);
    let mut sound = scene.play_at(source, position);

    sound.set_velocity(velocity);
    for i in 0..1000 {
        position[0] += velocity[0];
        position[1] += velocity[1];
        position[2] += velocity[2];
        sound.adjust_position(position);
        std::thread::sleep(std::time::Duration::from_millis(10));
    }
}

I even put the headphones on backwards to make sure I wasn't just imagining it. Did a blind test with another person as well. Sounds positioned on the right sound centered.

Make the `play_at` API accept other sample types than f32.

Currently the play_at function expects sources with sample type f32 because that is what's internally used.

Converting sources from other types requires annoying boilerplate #5.

It should be possible to make the function generic to accept any type that can be safely cast to f32.

Demonstration Video

I made a video demonstrating how Ambisonic is able to work in a 3D game I'd like to share with you. I thought maybe it could be useful for promoting the library with a real-world example.

Feel free to close.
:)

HRTF causes underrun in ALSA

I tried to run the examples, which use HRTF, and I always get this error:

ALSA lib pcm.c:8545:(snd_pcm_recover) underrun occurred

Not sure, if that's a bug in ambisonic or if I have to change my system settings.

Questions about positioning sounds

Hello!

I'm trying to adopt this for my game engine, and it's hard to understand how the positioning is working.

First of all, I cannot hear anything when a sound source is at 0, 0, 0. But I can hear when it is at 0, 0.0001, 0 and sort of. Why I cannot hear sounds of origin? Is there documentations about this?

Second, which dimension the X, Y and Z represents? Maybe, X for left-to-right, Y for down-to-up, Z for back-to-front?

I'm sorry for bothering you, thanks!

Physically correct distance-attenuation

The current distance-attenuation is just an ad-hoc 1 / d^2 formula with a cap for small distances.

Of course, attenuation depends on the medium the sound travels in and on the scene geometry (compare an open space vs. inside a narrow pipe). Some simplifications will be required.

Furthermore, it may be necessary to introduce a proper loudness model (power, sound pressure level, etc) in order to clarify what attenuation actually means.

TODO

  • rehearse sound propagation physics
  • define a simple/fast and physically correctish model
  • Pull Request

How to restart stream after pause/stop?

Hi again, since you requested feedback I wanted to create another issue for this question. Is it possible to pause a stream? I don't see this in the SoundController:

pub fn stop(&self);
pub fn set_doppler_factor(&mut self, factor: f32);
pub fn set_velocity(&mut self, vel: [f32; 3]);
pub fn adjust_position(&mut self, pos: [f32; 3]);
pub fn set_position(&mut self, pos: [f32; 3]);

In rodio stop() drops all the bytes from the stream, and playing again after a stream isn't possible it seems. Pausing a stream does work for me using rodio. It is possible to allow me to pause the sound using the SoundController and then play it again in ambisonic?

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.