Git Product home page Git Product logo

Comments (18)

DeXP avatar DeXP commented on May 3, 2024 1

How about SDL? Yep, it's too fat dependency in general case. But Steam requires SDL as a dependency in Linux. Also, SDL is the most common game-library, used in Linux. It's preinstalled on almost all Linux-machines.
One more advantage of SDL - it supports a lot of backends: ALSA, OSS, PulseAudio etc. It will work on any Linux distro, does not depend on wich sound system was used.
As an additional profit - a lot of supported OSes, Android included.

from cute_headers.

RandyGaul avatar RandyGaul commented on May 3, 2024 1

Finished! Thanks to @DeXP the port was very painless. There was one bug that you seemed to be struggling with. In the initialization wanted.samples should be a low value, since that's the internal buffer size, and will dictate how often SDL asks for samples. I set it to 1024 since that seemed to be the lowest it could go without any audio glitches. This should be good enough for people running at 30 fps as well -- but I haven't tested it yet!

I believe you were setting wanted.samples to a very large value (the size of the context's internal buffer).

Cheers!

from cute_headers.

RandyGaul avatar RandyGaul commented on May 3, 2024

I would totally happy with an SDL port! This is a pretty good idea. The header itself can run natively on Windows/Apple operating systems already, so adding in the final port as SDL would be a great option. SDL port can be enabled in the header via pre processor very easily.

from cute_headers.

RandyGaul avatar RandyGaul commented on May 3, 2024

Obviously, though, SDL_Mixer should have nothing to do with tinysound. I originally wrote tinysound because I hated SDL_Mixer API.

from cute_headers.

DeXP avatar DeXP commented on May 3, 2024

Ok, I have compiled basic skeleton. Now it's only left to make music work! x-D
How does tsMix works? At start I ask TinySound "please, prebuf 5 seconds for me", but I call tsMix every 10 ms. It must mix all current sounds into one? Only current 10ms slice? Why GetCurrentPosition used in Windows? Do you calculate it by yourself in Mac?
P.S. I have not found any function for Yield in SDL. :-(

from cute_headers.

RandyGaul avatar RandyGaul commented on May 3, 2024

Yep tsMix mixes all sounds together. Yep, tsMix keeps a latency buffer of samples. GetCurrentPosition gets positions of circular buffer inside of DirectSound. On Mac the circular buffer must be implemented manually. You can call tsMix at whatever interval you like (10 ms is a perfectly acceptable interval), but it should be less than half of the latency buffer (to make sure it is impossible for DirectSound to read garbage values, on Mac there would just be silence in this case).

I don't know about Yield in SDL. Is it possible for SDL to just expose a buffer? In that case tsMix can write to this buffer in a circular manner... Not sure if this is possible (I didn't look deeply into SDL API yet).

More info:

tsMix will try to buffer the latency ahead of where the underlying API reads samples. So for DirectSound, it gives you a play_cursor and write_cursor. You write samples to the write_cursor with tsMix, and tsMix will generally keep the write_cursor latency_seconds ahead of the play_cursor. DirectSound will be reading samples and playing them from the play_cursor. These cursors come from GetCurrentPosition.

For Mac I implemented the delay myself, but it is identical to DirectSound. Samples are written a little ahead of where CoreAudio reads. There is a buffer of latency samples between the reading and the writing. In between is a circular buffer. On Mac I had to implement the circular buffer explicitly. In DirectSound the circular buffer is mostly hidden within DirectSound.

from cute_headers.

RandyGaul avatar RandyGaul commented on May 3, 2024

I looked into SDL here: https://wiki.libsdl.org/SDL_AudioSpec

This should work. SDL_AudioCallback can be setup very similarly to tsMemcpyToCA here. It looks like this callback just requests more data as needed, and can use the circular buffer implemented for Apple.

from cute_headers.

RandyGaul avatar RandyGaul commented on May 3, 2024

Oh one note. This might be easier to implement https://wiki.libsdl.org/SDL_QueueAudio. This can be called at the end of tsMix.

These are just suggestions! I haven't actually ever used the SDL audio API before so these might not work.

from cute_headers.

DeXP avatar DeXP commented on May 3, 2024

Great thanks! SDL_QueueAudio helped a lot. The porting in active process now.
https://github.com/DeXP/tinyheaders/blob/master/tinysound.h
What is working:

  1. Low- and High-level API
  2. Threads / thread pool
  3. One audio stream
    What is currently not:
  4. The sound output for right channel only. o_O
    When it will be ready, I will prepare a pull request.

from cute_headers.

RandyGaul avatar RandyGaul commented on May 3, 2024

Looks pretty good overall. I noticed a small bug here: https://github.com/DeXP/tinyheaders/blob/master/tinysound.h#L1620

To set samples_to_write it looks like SDL provides: https://wiki.libsdl.org/SDL_GetQueuedAudioSize Then it is possible to do:

int queued_samples = SDL_GetQueuedAudioSize( ctx->dev );
int latency_samples = ctx->latency;
TS_ASSERT( queued_samples <= latency_samples );
int samples_to_write = latency_samples - queued_samples;

Also I think you want AUDIO_S16SYS instead of AUDIO_S16LSB in tsMakeContext.

from cute_headers.

DeXP avatar DeXP commented on May 3, 2024

Now it's much better. I still have some problems with SDL_GetQueuedAudioSize - it always return buffer size for small buffers. I thinked to always have exactly 2 buffers of the fixed small size. But it's glitchy too... For latency_in_Hz = 15 I need to have 5 of them. :-(
https://github.com/DeXP/tinyheaders/blob/master/tinysound.h#L1627
I'm thinking about rewriting it to own implemented ring-buffer, as it shown here.

from cute_headers.

RandyGaul avatar RandyGaul commented on May 3, 2024

tsMemcpytoCA is using a ring buffer implementation. I would recommend using that and using the Mac implementation as a reference.

from cute_headers.

RandyGaul avatar RandyGaul commented on May 3, 2024

Hmm I looked into SDL_GetQueuedAudioSize and from the docs:

This is the number of bytes that have been queued for playback with SDL_QueueAudio(), but have not yet been sent to the hardware. This number may shrink at any time, so this only informs of pending data.

So this can not be used to determine latency samples. That's why it always gives you tiny numbers, as it is probably very quickly pushing data to the underlying API.

Unfortunately the only solution here is to use SDL's callback SDL_AudioCallback, which will be called by SDL periodically when it needs more audio data -- this is nearly identical to the ring buffer implementation for Mac in tinysound.

from cute_headers.

DeXP avatar DeXP commented on May 3, 2024

Yep, I know already about Queue-functions. My game was already Greenlit: Wordlase. So I temporary moved my forces to complete the papers. Now I can return to work on engine.
Also, I really need API to load OGG dynamically. Not preload all file and decode it. But get only needed short data chunk. It will really reduce the memory usage...

from cute_headers.

RandyGaul avatar RandyGaul commented on May 3, 2024

Hey that is a very cute looking game! :)

AFAIK stb_vorbis can do streaming of ogg files: https://nothings.org/stb_vorbis/samples/sample.c

Check out uhh the pull_data API (in stb_vorbis.c look for STB_VORBIS_NO_PULLDATA_API section, here it is). That is probably the easiest to use. You can hand a FILE* to stb_vorbis and it can progressively pull data out of the file. This way the entire audio does not need to sit in RAM uncompressed (which is what tinysound currently does).

If you don't like pulling (which requires callbacks) there's a push_data API, which instead of using callbacks to request data, the user gives stb_vorbis data as needed through a "push buffer" style. I personally would use pull API, but push API might be easier to heavily optimize.


I figured storing entire file in RAM is OK for tinysound since users will probably have file-loading on a separate thread, so the ~1 second of latency for decoding a vorbis stream should be acceptable. Especially as time goes on people have better hardware with lots of RAM. It is also very simple code to implement, so no room for bugs and easy to modify.

But, it would definitely be nicer to have some special API for .ogg music files to use less RAM. Problem is this kind of system is very tricky to implement. Have to handle the latency buffer as it crosses from one audio packet to the next, and pull in packet streams as needed. All the machinery is a lot of work to implement. It is also harder for users to use an API dedicated to special music -- the current tinysound API unifies all sounds and music, so users need to implement less code to use tinysound.

from cute_headers.

r-lyeh-archived avatar r-lyeh-archived commented on May 3, 2024

An ALSA backend would be a great addition as well
FYI, http://github.com/yui0/aplay-/blob/master/alsa.h (PD)

from cute_headers.

RandyGaul avatar RandyGaul commented on May 3, 2024

@DeXP Ganna take a crack at this today and see if I can knock it out. Thanks for posting up your work so far! I'll start work from where you left off.

from cute_headers.

RandyGaul avatar RandyGaul commented on May 3, 2024

@r-lyeh That would be really sweet. Unfortunately that is something I will not be able to do myself. Feel free to open a new issue on that topic! Maybe someone will come along and add it one day :)

from cute_headers.

Related Issues (20)

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.