Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

1370445 Posts in 64468 Topics- by 56531 Members - Latest Member: thedrawingmiller

December 15, 2019, 08:38:28 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)plaid/audio 0.2 - free portable audio framework
Pages: 1 [2] 3
Print
Author Topic: plaid/audio 0.2 - free portable audio framework  (Read 15884 times)
Evan Balster
Level 10
*****


I live in this head.


View Profile WWW
« Reply #20 on: December 27, 2012, 07:59:28 PM »

Ref safety:  All the audio classes derive from RefCounted and contain their own reference count, allowing multiple Ref<T> to be instantiated safely from their pointers.  The new code in 0.2.0 splits Ref<T> into Ref<T> (for RefCounted types) and the less-safe AutoRef<T> which works with anything, requires explicit construction and has safety warnings all over it.  The latter isn't used anywhere in the engine and is provided to retain compatibility with arbitrary types.

C++11:  Portability is a big goal with this audio engine and sadly support for C++11 is still far from universal.  I'm going to hold off until I feel assured all major target platforms for games (including closed ones like consoles) are safe.  Sad

Object copies:  Nope, just ref-counted pointers.

Code:
typedef Ref<AudioStream> Sound;

Sound and Signal are both safe to copy.  It's an encapsulation scheme I use all over the larger game engine and allows me to treat many of my C++ classes like C#-style reference objects.  Copying any actual audio object (derived from AudioStream) is illegal and will not compile.
Logged

Creativity births expression.  Curiosity births exploration.
Our work is as soil to these seeds; our art is what grows from them...


Wreath, SoundSelf, Infinite Blank, Cave Story+, <plaid/audio>
Klaim
Level 10
*****



View Profile WWW
« Reply #21 on: December 28, 2012, 01:39:24 AM »

Ok, it was not clear from the typedef names. Did you consider adding Ptr or Ref as suffix to clarify that it's a kind of pointer?

By the way, is your pointer thread-safe?
Logged

Evan Balster
Level 10
*****


I live in this head.


View Profile WWW
« Reply #22 on: December 28, 2012, 09:02:16 AM »

Ref is not especially thread-safe, no.  It's expected that audio will be controlled from a single thread.  The multithreading and resource management between the control thread and the audio thread is safe as long as this is the case.
Logged

Creativity births expression.  Curiosity births exploration.
Our work is as soil to these seeds; our art is what grows from them...


Wreath, SoundSelf, Infinite Blank, Cave Story+, <plaid/audio>
Overkill
Level 3
***


Andrew G. Crowell


View Profile WWW
« Reply #23 on: December 28, 2012, 10:48:15 AM »

Actually, I won't private message, I can just dump things here, I suppose.

Yeah I figured there was some justification for the non-interleaved buffers, and I guess I might have to toy with adding some custom effects to the master Mixer, if that is possible, because it'd be nice to have a master pitch shift/pan in addition to the volume shifting already available. I currently do this effect application per active sample played in the update call to simulate having a master control with all of those effects, it's sort of a hack.

Hmm, my wav parser might need a bit of work to be standalone lib, haha, but it shouldn't be toooooo bad. I need to headbash some more and it'll hopefully come together. Main concerns are endianness (and the fact there are two RIFF formats depending on host machine saved), and that WAV can either be different bitdepths, so I need to scale them up to a common depth. I'll try and throw something together eventually.

Here is the modplug codec by the way (uses my custom file wrapper, but really, you could just use a FILE* or whatever): https://github.com/Bananattack/Plum/blob/master/source/plum/platform/plaidaudio/codec_modplug.cpp

Your face may melt if you read my code too much, because it's heavily work-in-progress, and I'm refactoring the hell out of code I started around 2008, and my first priority was getting every dependency in the engine to be permissively licensed. Feel free to look around, if it seems interesting, and check out test/Maximum Yak Maniac/ and run Plum.exe if you want to try a silly little test app.
« Last Edit: December 30, 2012, 01:38:39 PM by Overkill » Logged

Evan Balster
Level 10
*****


I live in this head.


View Profile WWW
« Reply #24 on: December 28, 2012, 12:01:20 PM »

Nice!  :D

There's an easy and practical workaround for the lack of a master effect pipeline now -- just create another Mixer, pass its output through a bunch of effects, and route the output to the master mixer.  Even if I do add a master effect chain that will generally be the better way to do things since you might want alerts or something that aren't affected.

An _awesome_ trick if you're going to do this is to waver the pitch shift up and down about one semitone with a ~1-2 hz sine wave.  It'll make your game sound like a crappy VHS tape.

Checking out Maximum Yak Maniac now...

EDIT:  How I downloaded github folder?  ;_;
« Last Edit: December 28, 2012, 12:11:12 PM by Evan Balster » Logged

Creativity births expression.  Curiosity births exploration.
Our work is as soil to these seeds; our art is what grows from them...


Wreath, SoundSelf, Infinite Blank, Cave Story+, <plaid/audio>
Overkill
Level 3
***


Andrew G. Crowell


View Profile WWW
« Reply #25 on: December 28, 2012, 12:44:49 PM »

EDIT:  How I downloaded github folder?  ;_;
Yeah github won't show the download link if you go to source view apparently anymore, wtf Sad So my repo is: https://github.com/Bananattack/Plum -- click the button that says "ZIP" that's under the repo description, and beside the SSH/HTTP/etc clone URLs.
Logged

Evan Balster
Level 10
*****


I live in this head.


View Profile WWW
« Reply #26 on: December 28, 2012, 02:44:40 PM »

I haven't got any sound at all!  D:
Logged

Creativity births expression.  Curiosity births exploration.
Our work is as soil to these seeds; our art is what grows from them...


Wreath, SoundSelf, Infinite Blank, Cave Story+, <plaid/audio>
Klaim
Level 10
*****



View Profile WWW
« Reply #27 on: December 28, 2012, 03:04:40 PM »

Ref is not especially thread-safe, no.  It's expected that audio will be controlled from a single thread.  The multithreading and resource management between the control thread and the audio thread is safe as long as this is the case.

Then I have two remarks:

 - know that std::shared_ptr is thread safe, it uses an atomic counter for reference counting and copy is guaranteed to be thread safe too. If one day you replace your impl by this, you should be aware of it.
 - unfortunately I will certainly not be able to test your library. It would force me to add a thread only to control the audio library that already will have it's own thread I suppose. The rest of my code is not guaranteed to be executed by the same thread all the time so it's a problem. I don't know if FMod have a thread safe interface, I should check this too.

Logged

Overkill
Level 3
***


Andrew G. Crowell


View Profile WWW
« Reply #28 on: December 28, 2012, 04:23:09 PM »

I haven't got any sound at all!  D:

Doh, I'm dumb. Open plum.cfg, remove the line that says "silent" haha. Sorry I forgot to check that. But hey, headless mode works too!
Logged

Evan Balster
Level 10
*****


I live in this head.


View Profile WWW
« Reply #29 on: December 28, 2012, 09:55:18 PM »

Klaim:  Tell me about the threading scheme in your game engine.  I'm interested in use cases.  Also, how do you handle your graphics?  I know OpenGL never multithreads well; does DirectX?

Overkill:  Got the audio working.  Whoever talked about logspam earlier wasn't kidding -- printing stuff to the console from the audio thread is baaad, that's why the audio engine is misbehaving so badly.  Sorry for shipping the temp code like that.  Sounded fine otherwise.
Logged

Creativity births expression.  Curiosity births exploration.
Our work is as soil to these seeds; our art is what grows from them...


Wreath, SoundSelf, Infinite Blank, Cave Story+, <plaid/audio>
Klaim
Level 10
*****



View Profile WWW
« Reply #30 on: December 29, 2012, 01:40:17 AM »

Klaim:  Tell me about the threading scheme in your game engine.  I'm interested in use cases.  Also, how do you handle your graphics?  I know OpenGL never multithreads well; does DirectX?

Indeed OpenGL don't multithreads well (maybe in future versions apparently it will behave better). I'm forced to have a specific thread for graphics, which is very annoying but always necessary anyway and I don't have yet the real impact of this on overall performance (graphics will certainly not be the bottleneck, but I'll see when the game is complete). I still have graphic resource loading going concurrently though (using Ogre and tbb task scheduler).
At least the graphic thread is alone, it don't spawn other threads like a audio or network library should. So basically I will have 3 threads plus tbb task manager and I suspect it's already not a perfect balance. As I said the game is not complete enough to check this.

What I was saying is that if your library already have it's internal thread, I shouldn't have to have another specific thread just to give it commands.
Logged

Overkill
Level 3
***


Andrew G. Crowell


View Profile WWW
« Reply #31 on: December 29, 2012, 07:37:29 PM »

Overkill:  Got the audio working.  Whoever talked about logspam earlier wasn't kidding -- printing stuff to the console from the audio thread is baaad, that's why the audio engine is misbehaving so badly.  Sorry for shipping the temp code like that.  Sounded fine otherwise.

Heh, you're right! Removing the logspam from the .ogg decoder basically fixed all the performance issues. Awesome. :D
« Last Edit: December 29, 2012, 08:42:26 PM by Overkill » Logged

Evan Balster
Level 10
*****


I live in this head.


View Profile WWW
« Reply #32 on: December 30, 2012, 07:47:38 AM »

What I was saying is that if your library already have it's internal thread, I shouldn't have to have another specific thread just to give it commands.

I could easily have written the library so it wouldn't be a problem, but I had a specific goal: syncing the audio timeslices to an external framerate which is generally expected to be the rate for game logic, thus facilitating consistent time deltas between subsequent visual and aural events.  It's very rare for game logic to be split into multiple threads without creating a point in time where all logic is complete and a final step is taken -- if there is such a final step, then it's perfectly possible to use the audio engine.

If you did satisfy that requirement, you would need to ensure each audio stream's front-end (settings) is controlled by only one game logic thread, and that none of those threads are at risk of manipulating those settings during the "final step" at which point you make the call to Audio::update().  This function "sends" the settings to the callback thread, so it's reading all of them.  You also want to ensure all calls to Audio's interface happen from only one thread, which you could make less of a pain by giving each of your controlling threads a separate Mixer attached to the master to play their own sounds on.

Or if you can't make any guarantees whatsoever, just make multiple copies of the audio engine.  Roll Eyes
Logged

Creativity births expression.  Curiosity births exploration.
Our work is as soil to these seeds; our art is what grows from them...


Wreath, SoundSelf, Infinite Blank, Cave Story+, <plaid/audio>
Klaim
Level 10
*****



View Profile WWW
« Reply #33 on: December 30, 2012, 11:21:00 AM »

I fully understand your point, however you assume that the game logic is in a "game-logic thread" while the correct way of thinking about it (and you almost said it like that in the first paragraph) is that there is a game-logic specific time step, which is unrelated to threading. Whatever the way you do it, if you have your game logic in a specific locked time-step allowing, indeed, output libraries (like graphic and audio) to react relatively to this time-step, then you get the good behavior. In my case, there is two things: the game logic happen on the server, so I don't care about an audio lib (it's a client/server setup even in solo mode); the client-specific-game-logic that mostly react to network events (from the server), which means I can't totally guarantee the precision of the time-step, but in my case (which is not an action game) it is not really important (what is important is mostly what happen on the server only).

So I do have some kind of game logic update, but it's not guaranteed to be executed by a specific thread. I believe some console game engines works this way too, using message queues to send audio directives to output-specific threads (or something like that).
Also, in a lot of engines, even if there is only one thread, game-logic update might be not in sync with inputs and output updates, so I'm not sure if you meant that you target this case too?

I'm still interested in your library and I think maybe there is some concerns about making it thread-safe as it would lower the performance for more classical contexts. I'll try to fit it in my system, see what is needed to make it work correctly in this context and report for potential enhancement that would help multi-threaded contexts without impacting other cases. When I'll be working on audio (not now but in a few days/weeks I think), I'll try it. Worse case, I could just call the update in sync with the graphic rendering as it is already in it's own thread (because of OGL limitation, as explained) - which would be what you suggested anyway.

I understand I'm not in a classic case, don't worry too much about this; please continue to improve the library for most cases, it really looks promising (and less prone to be abandonned llike CAudio).
I'll try to help if I figure some improvements. Wink
Logged

Cheezmeister
Level 3
***



View Profile
« Reply #34 on: December 30, 2012, 12:54:49 PM »

Panning commonly uses an "equal-power" or "constant-power" crossfade defined by the sin and cos of the pan value (times pi/2), rather than a linear fade. This is because linear weakens the output at the center values. There are reasons to use both kinds of fade though.

That...explains why my panning sounds so crappy. Kudos to you sir!
Logged

෴Me෴ @chzmstr | www.luchenlabs.com ቒMadeቓ RA | Nextris | Chromathud   ᙍMakingᙌCheezus II (Devlog)
nikki
Level 10
*****


View Profile
« Reply #35 on: April 05, 2013, 11:21:04 PM »

slightly op but :

what are these openAL multi-platform inconsistencies ?
I'd like to know that before sinking more time in openAL atm.
Logged
ThemsAllTook
Global Moderator
Level 10
******



View Profile WWW
« Reply #36 on: April 06, 2013, 07:23:07 AM »

what are these openAL multi-platform inconsistencies ?

My experience with OpenAL: Works OK on Mac, Linux, and iPhone, but Windows is a nightmare. First thing I ran into is that there are two different implementations to choose from: OpenAL-soft, and Creative OpenAL. OpenAL-soft had very high latency when I tried it, and I couldn't find a way around that. It also crashed on exit if I hadn't explicitly disposed of all of my sources and buffers (WTF?), so I had to add an atexit() handler just for that.

Creative OpenAL solved these two problems, but introduced a new one: The first two sources I played always had some sort of low-pass filter effect enabled, and I couldn't for the life of me figure out how to turn it off. I tried to get around it by creating a couple of sources at startup and never using them, but even that didn't work. I think I was able to fix it by playing a short silence sound through those two sources at startup, then never using them again.

Another issue that didn't have to do with platform inconsistencies, but ultimately caused me to switch to portaudio: OpenAL gives you very little control over how positional sound is rendered. I was using it for a top-down 2D game, and I wanted sounds to the left and right of the player to gently pan to one side or the other as they get farther toward the edge of the screen. However, moving a sound even a fraction to the left or the right made it play completely in that channel and not at all in the other one. This is probably fine for a first-person game, but just didn't suit my needs at the time.
Logged

Evan Balster
Level 10
*****


I live in this head.


View Profile WWW
« Reply #37 on: April 06, 2013, 09:03:30 PM »

<plaid/audio> will most likely be expanding a *lot* over the course of the next year, for SUPER SECRET reasons!  I've been preoccupied these last few months with SoundSelf and its Kickstarter, but I should be starting to sink a lot more time into the audio engine within the next month or two.  So consider the development horizon very sunny.

My two cents on OpenAL:  OpenAL's API calls take the form of "do this", whereas OpenGL (in the spirit of which it was conceived) has an API of the form "do this, this way."  Thus a great deal of behaviors -- such as the spatialization model -- are left undefined.  It's also designed as a hardware language, and "gaming soundcards" are pretty much done for.  CPUs, on the other hand, are increasing in speed and core count, making software audio processing as is done in FMOD and my system more viable by the day.

It's also my opinion that OpenAL's API design is terrible for audio; in the best of worlds, my work will help drive it into obsolescence.
Logged

Creativity births expression.  Curiosity births exploration.
Our work is as soil to these seeds; our art is what grows from them...


Wreath, SoundSelf, Infinite Blank, Cave Story+, <plaid/audio>
Evan Balster
Level 10
*****


I live in this head.


View Profile WWW
« Reply #38 on: April 07, 2013, 09:33:15 AM »

<plaid/audio> works fine on Mac.  I've noted a nasty bug on Linux related to thread safety of an ALSA timer function, though.

Github is a maybe.  It's a little bit of a deviation from my usual workflow, but I'm definitely interested.  Does anyone here know how I can nest repositories locally?
Logged

Creativity births expression.  Curiosity births exploration.
Our work is as soil to these seeds; our art is what grows from them...


Wreath, SoundSelf, Infinite Blank, Cave Story+, <plaid/audio>
Evan Balster
Level 10
*****


I live in this head.


View Profile WWW
« Reply #39 on: April 07, 2013, 12:03:02 PM »

This audio engine is a component of a larger system which I haven't opensourced.  It would be nice to be able to have a sub-folder of the <plaid/audio> repository living inside my project repository.  Anyway, I understand there are tricks for achieving this, they're just complicated.  Nothing worth cluttering the topic over.
Logged

Creativity births expression.  Curiosity births exploration.
Our work is as soil to these seeds; our art is what grows from them...


Wreath, SoundSelf, Infinite Blank, Cave Story+, <plaid/audio>
Pages: 1 [2] 3
Print
Jump to:  

Theme orange-lt created by panic