quad-snd icon indicating copy to clipboard operation
quad-snd copied to clipboard

Allow audio generation

Open comcloudway opened this issue 4 years ago • 10 comments

Not every game neccessarilly wants to play prerecorded audio files, rather they might want to generate the audio in real time.

To do this the Mixer would have to be exposed publically or rather the AudioContext would have to have an option to specify if the sample should be loaded from a file or the buffer should be filled using a callback or a second thread.

I'm thinking of a sgstem similar to how rust-sdl2 handles it: example can be found in their docs

struct SquareWave {
    phase_inc: f32,
    phase: f32,
    volume: f32
}

impl AudioCallback for SquareWave {
    type Channel = f32;

    fn callback(&mut self, out: &mut [f32]) {
        // Generate a square wave
        for x in out.iter_mut() {
            *x = if self.phase <= 0.5 {
                self.volume
            } else {
                -self.volume
            };
            self.phase = (self.phase + self.phase_inc) % 1.0;
        }
    }
}

I'm not completely sure if and how this could be implemented for all the supported platforms, but looking at the alsa module for linux, the mixer already had a function to fill a given buffer

comcloudway avatar Mar 12 '22 13:03 comcloudway

Hi! It would be nice to have, but, realistically - its a bit out of a scope of quad-snd. quad-snd is quite a minimum thing that used just for macroquad and advanced audio tricks are not really close in the roadmap.

I would recommend doing a fork, especially if you interested in just one platform, quad-snd is designed to be very fork-friendly

not-fl3 avatar Mar 12 '22 17:03 not-fl3

Yeah I will try forking it - I was actually hoping for cross platform (linux, web, android) but maybe I can get that working.

I've read that quad-snd is supposed to be minimal, but from my understanding the low-level audio playback always involves filling a buffer, which is why I though that maybe exposing it would be possible.

But thanks for your reply

comcloudway avatar Mar 12 '22 18:03 comcloudway

It does on all the platforms except web. On the web it is easier to use higher-level webaudio abstractions instead of dealing with the buffers - it allows to skip threading and web workers and significantly win in performance.

Not the best decision for a general-purpose library for sure, but so far works quite well for macroquad.

not-fl3 avatar Mar 12 '22 19:03 not-fl3

I've finished the Android, Linux and Windows buffer based code in my fork (I've only tested my example on Linux so far).

As I do not expect it to be merged at any point (one won't ever need both features at the same time), I've removed/plan on removing the Mixer and file loading part completely.

Unfortunately I'm currently stuck with the coreaudio version, because I honestly do not understand why the saudio_coreaudio_callback takes a c_void.
I know that the coreaudio module was generated from the C code, but I wasn't able to find anything helpful in the Apple Developer Documentation and am not nearly comfortable enough to work of the C code.
So I wanted to ask if you might have some addition material, like you have mentioned in the other files.

EDIT: I've just noticed that I misread the code and was looking for a wrong function name in the docs, I found it this time here

comcloudway avatar Mar 13 '22 10:03 comcloudway

Nice, glad it worked!

quad-snd was designed to be very copy-paste friendly - take some code out of quad-snd, there is not much of it, actually, and build something that suits you better :)

coreaudio.rs was auto-generated, yes. You might want to use https://github.com/RustAudio/coreaudio-rs if you want to use way more functions, but I would just keep hand-adding binding to the required functions to coreaudio.rs, it doesn't take too much time while keeping things simple

not-fl3 avatar Mar 13 '22 14:03 not-fl3

Thanks I will certainly have a look at that.

I just finished porting my old rust-sdl2 based app to miniquad, because I want it to run on android.
I have some performance issues, but I'm sure I'll be able to solve them (reading & writing RwLocks from the UI-thread, I probably have to look at miniquad render fps settings or some thing like that).

Again thank you for your support, I don't know if you want to keep this issue open - if you keep it open, I will probably do an update when I get the macOS and web stuff working, but I don't mind if you close the issue

EDIT: Midi will obviously be disabled on android, as I was unable to get that working in a miniquad fork - I got lost in the JNI crate, more can be found on my seperate miniquad issue EDIT2: The audio issues do not come from miniquad nor my quad-snd fork, apparently my other code is bad EDIT3: Turns out buffer generation in rust is weird, it doesn't really work in debug mode, but in release mode it works flawlessly

comcloudway avatar Mar 13 '22 14:03 comcloudway

I have a question related to your version of the library: Have you tested the android version? And if you did, does the audio play without skipping beats or production clicking sounds?

Trying to find out if my software is broken or if I may have introduced a bug into my fork

comcloudway avatar May 22 '22 16:05 comcloudway

I have a question related to your version of the library: Have you tested the android version? And if you did, does the audio play without skipping beats or production clicking sounds?

Trying to find out if my software is broken or if I may have introduced a bug into my fork

I believe it worked well, at least here https://play.google.com/store/apps/details?id=rust.zemeroth&hl=en&gl=US I can't hear any sound artifacts

not-fl3 avatar May 22 '22 18:05 not-fl3

Ok, so I don't really understand why it wasn't working - I noticed that you were filling two channels and I had apparently deleted those calls in my fork. It is working now thanks

comcloudway avatar May 23 '22 16:05 comcloudway