Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Foobar event/push mode (Read 37666 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Foobar event/push mode

Hello,

I am exploring foobar which is a great player.

I tried to overcome DirectSound by using WASAPI. Generally is it written that event/push style of WASAPI differs only with the method of sending sound, e.g. the output is bit perfect in both cases.

But it seems not and I am not alone, as e.g. here http://www.hifivision.com/computer-audio/55644-foobar2000-wasapi-settings.html a user says the same I seem to be hearing on some tracks  (on two computers so it cannot be simple configuration issue) - the event and push mode very slightly differ in sound, the push mode being a little bit softer and flatter and the event mode being more crisp.

And now the questions:

1. What is the cause and if it is placebo how can it be proven?
2. If it really makes a difference which mode should I use to get more "hifi" playback?

Thanks,

Jan

Re: Foobar event/push mode

Reply #1
So-called push and pull, or timer and event processing, do the same thing.  Simply stated, one is based on a timer (update the buffer every x milliseconds) and the other is based on an event (update the buffer when the lower-level driver says it is ready to accept more).   There is no reason to believe anything is different just because of that.

There are also exclusive and shared modes.  Each of those can be fed by push or pull.  If you want to make an argument, you have to go with those modes, not pushing or pulling to fill a buffer.  I suggest not bothering and instead, angle your speakers in a bit. 1001x more difference.
BANNED

Re: Foobar event/push mode

Reply #2
I don't  know the exact implementation of the push method in foobar2000, but a timer is not at the root of the concept.
Event and push differ in who is responsible to decide that more data is needed on the buffers.

Event based implementation has a callback method that is called by the driver/API when it has determined that more data is needed (usually, this is triggered when a previously prepared buffer is about to be played).

Push based implementation has a loop in its own thread which asks repetitively to the driver if it is ready to receive a new buffer (which is also related to the previous buffer going to be played).

An Event based implementation is expected to allow lower latencies since the calling application is notified at the exact moment that it can prepare a new buffer, whereas with push based ones, the implementations has a delay (in form of a short sleep, so that the loop is not constantly using CPU resources), and as such, it doesn't react immediately.
I am guessing that a timer based push implementation would have a timer that is fired at least twice for each buffer duration to check if it can prepare another buffer. I say twice, because the timer would not be precise enough to run exactly at the speed that the driver consumes the buffers.

In foobar2000, both push and event use the exclusive mode of operation (the one that bypasses the mixer and opens the driver directly, blocking other applications out). The only way that they could be different is if the application generated a different buffer (very illogical suposition to have), or the driver applied a different processing (if any) to the buffer (also quite strange to believe).

What I read in that thread you posted seems to be more related to using different buffer settings than anything else. Very low latencies are only of use for realtime applications like music composition or DJ software, not for background tasks like an audio player. If 200 ms is too much, then, 50ms should be enough. My integrated soundcard is not able to go below 20ms with WASAPI exclusive on realtime software, while a new USB one that i bought that has ASIO drivers is able to go down to 2 milliseconds.


Re: Foobar event/push mode

Reply #4
And also I am not experienced in buffer size. I simply on some tracks can hear, that the sound is slightly different, the event being more crisp and "centered" and push being softer and widespaced. I personally like the push sound better, is there any caveats using it ?

Re: Foobar event/push mode

Reply #5
And one more "strange" thought - does the mentioned buffer size have effect on sound ? E.g. also when Event/Push mode is changed, the buffer could be changed accordingly and that could influence the sound ?


Re: Foobar event/push mode

Reply #7
OK, I can accept that I feel placebo, but I wonder why the others independently wrote similar things that I have felt.

Re: Foobar event/push mode

Reply #8
And also I am not experienced in buffer size. I simply on some tracks can hear, that the sound is slightly different, the event being more crisp and "centered" and push being softer and widespaced. I personally like the push sound better, is there any caveats using it ?

Almost any media player supporting WASAPI started with push mode and later added the event mode.
This because a lot of USB DACs had problems with the push mode, most of all buffer underruns.

If you don’t have this problem, you can choose the one that sounds best to you.

A possible explanation for differences is “noise”.
Different modes of processing can generate different patterns of EMI/RFI/ripple on the ground plane/etc. If we assume this creeps into the DAC and modulates the analog out some way, we do have an explanation for possible differences.

However, if this is the case it should be easy to measure.
These measurements are rare, very rare indeed.
On the other hand, boxes claiming to isolate the DAC from the PC are a very prolific market.
Noise has become the new jitter :)


TheWellTemperedComputer.com

Re: Foobar event/push mode

Reply #9
Thank you very much for trying to find the real causes of the observed or perceived things. Yes, I use internal cards, not external DACs so this could be, theoretically, the case.

I have no problems with push mode performance so I will probably keep using it.

Still wondering which of those two modes is more "hifi", as personal preference is one thing and the actual output is the second ....

Re: Foobar event/push mode

Reply #10
I did a quick test with the WASAPI output in both push and event modes by using a WAV rip of Alan Parson's On Air. The album is a 5.1 DTS encoded signal, and must be sent through to the receiver untouched to be correctly decoded.

Using both WASAPI push and event modes work perfectly, while DirectSound just produces static. If event or push modified the signal in any way , the result would be static (as is the case with DirectSound), and the DTS stream wouldn't decode.

So if you are hearing a difference between push and event, then it's certainly not coming from the WASAPI output plugin. In any case just use what works, and what you think sounds better!

Re: Foobar event/push mode

Reply #11
Thank you very much! Happy to know that none of the modes is wrong in principle and there are probably (as in all case when theory says something and reality show some signs of difference) other factors.

Will probably keep using push as it runs great technically and on some tracks sounds - i think on my equipment - better.

Re: Foobar event/push mode

Reply #12
I don't  know the exact implementation of the push method in foobar2000, but a timer is not at the root of the concept.
Windows Audio Session Application Programming Interface.    Nothing mystical going on.  A timer is certainly involved for the "push" method.  I take it you have never worked with WASAPI?  Anyway, I may have cut out more details than I needed to up top, but most wouldn't understand the details.  For you, I'll add this:  WaitForMultipleObjects() is a timer when a timeout is set.  If you don't know why that is, then you are doing it all wrong (sure, you could poll GetCurrentPadding() but that is just going to spin the CPU).

As for bit-perfect, most here probably don't know that all "shared" audio routes thought a limiter:

https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/a4c4b0a7-d5bc-4647-952e-1015de8cce27/24-bit-bit-perfect-audio-with-wasapi-shared-mode

BANNED

Re: Foobar event/push mode

Reply #13
I am using WASAPI push exclusive only (foobar).

Re: Foobar event/push mode

Reply #14
@40th.com  No. I've never worked with WASAPI (hint: it's an URL link).

When I say a timer is NOT at the core, I do mean so. You can implement it with a timer, and a timer implementation might have its good points, but you can build an implementation for push without a timer (A sleep and a timer are two different concepts for me, and definitely, a semaphore has nothing to do with a timer).


Re: Foobar event/push mode

Reply #15
Just a note: Default buffer sizes are different for WASAPI push/event mode.
See Settings->Advanced->Playback->WASAPI
It's called a hardware buffer there. Some have noticed instability with buffer sizes 90 or higher in event mode, while in push mode the default of 200 is fine.

In my experience it either works or I hear obvious glitches. Push gives me the best results too.
In theory, there is no difference between theory and practice. In practice there is.

Re: Foobar event/push mode

Reply #16
Quote from: [JAZ
When I say a timer is NOT at the core, I do mean so. You can implement it with a timer, and a timer implementation might have its good points, but you can build an implementation for push without a timer (A sleep and a timer are two different concepts for me, and definitely, a semaphore has nothing to do with a timer).
Look (listen?).  So-called push (to endpoint) feeds the buffer on a timer.  So-called pull (from endpoint) feeds the buffer on an event.  The timer is programmer-set-up (i.e., it fires on an interval set by the programmer). The event is initiated by the soundcard driver (i.e., it fires when the soundcard drivers says so -- much like back in the old days when we (some of us) programmed the DMA device directly.  That is all there is to this.  It's as simple as that.  What in this do you have a problem?  Be specific.
BANNED

Re: Foobar event/push mode

Reply #17
Just a note: Default buffer sizes are different for WASAPI push/event mode.
See Settings->Advanced->Playback->WASAPI
It's called a hardware buffer there. Some have noticed instability with buffer sizes 90 or higher in event mode, while in push mode the default of 200 is fine.
You are talking about a specific program.  Buffers are used differently depending on not just timer/event, but also shared/exclusive.  Any problems you see are not related to wasapi in general, but would be a bug in either the soundcard driver, the program, or both.  There are four different modes: event shared, event exclusive, timer shared, timer exclusive.  Of those, only event exclusive will do exactly what you tell it; if you give it a big buffer, it will eat exactly that big buffer whole hog.  The other three modes can and will piecemeal the buffer into smaller, pre-defined chunks, and in shared mode, you (can) just fill until you can't fill no more.  FWIW, I have ten soundcards here and none give me any problems using any wasapi mode and any size buffer, and this runs from new USB back to a decade-old X-Fi Elite Pro.
BANNED

Re: Foobar event/push mode

Reply #18
What in this do you have a problem?  Be specific.

I am objecting on either, your definition of "timer", or on the necessity of a timer, in the terms that I define a timer.

When I looked again at my Wasapi code, I saw I use WaitForSingleObject() (which you mentioned) and that one of its parameters indicates time. But that method is not a timer.

Concretely, the method would wait indefinitely until the object is available to the thread, but since we do not like deadlocks, we add a maximum time to wait for the object.
When that method returns, two things can happen: The object is no longer locked so we can feed a new buffer, or the object is still locked but the time elapsed, so we cannot yet feed the buffer. We continue (may let the program do other things,maybe also unlocking some objects), and wait again.

There is no timer in the essence of that specific block. I we didn't use the "maximum time" overloaded version of the method, there would be no concept of time in there, because it is simply a semaphore.

I didn't have enough programming knowledge in the days of DMA, but I do remember reading about IRQ, and I believe that such one was a true timer based implementation. (as opposed to what we are talking about here).

Re: Foobar event/push mode

Reply #19
Nope.  I mentioned WaitForMultipleObjects().  Your WaitForSingleObject() is seldom useful (might be useful when exiting a program, to wait on a thread handle to close).

As for being a timer, of course it is.  It's a timer that has a fast way of getting out (by setting an event yourself in another thread, or a system event).  If you're sitting on a Sleep(Ex) you're waiting until the time expires -- no way out until then.  Using WaitForMultipleObjects() you have a way out (as in, RIGHT NOW).  It also lets overlapped I/O complete while it's waiting.  It's commonly used as I've described.  You should look into it.

I can't tell what you are doing now, not from your description.  If it works then I suppose that's good enough.
I am objecting on either, your definition of "timer", or on the necessity of a timer, in the terms that I define a timer.
When I looked again at my Wasapi code, I saw I use WaitForSingleObject() (which you mentioned) and that one of its parameters indicates time. But that method is not a timer.
BANNED

Re: Foobar event/push mode

Reply #20
Then ok.
You have definitely made it quite clear that we disagree on the definition of timer.

For you, a timer is something that can be triggered on an event.  Well.. a mouse click could be a timer then too. It is just waiting there for that to happen.

For me, that will continue to be a semaphore, with a way out (the timer). Not the other way around.

Re: Foobar event/push mode

Reply #21
Then ok.
You have definitely made it quite clear that we disagree on the definition of timer.

40 is right, you are getting mixed up on details.

Plenty of Windows timers have events that can short circuit the timer.  Also timers can be implemented using interrupts or cycle counting, that's just an implementation detail.

Re: Foobar event/push mode

Reply #22
@saratoga:
If I can take two unrelated concepts, and by way of their implementation, made it to do the exact same thing, then, can you describe it as only "implementation details"?

Timer: a *time* based event that, after a defined amount of time (duh), does an action. (we can have blocking ones like sleep, or multithreaded based ones, like a cron job or an "onTimer()" event).

Semaphore: An access control mechanism that controls multi-process synchronization. Such control can mean that two threads (or thread types) do not access the same code block at the same time, or that a thread waits until some other threads has finished a previous work.

Is a semaphore a timer? Can a timer be a timer with no notion of time (other than.. "when done") ?  Can I use the words semaphore and timer interchangeably?

If the answer to those three questions is "no". Then, a timer is NOT a requirement of  Push based WASAPI (or push based anything), and my point stands.
Else, I live in a parallel world and I apologise for not knowing that I am there.

Re: Foobar event/push mode

Reply #23
@saratoga:
If I can take two unrelated concepts, and by way of their implementation, made it to do the exact same thing, then, can you describe it as only "implementation details"?

Yes.  A timer is a logical concept that exists independent of all possible implementations, as it must given that there are infinitely many possible ways to implement an abstract concept. 

Go ahead and implement a timer using semaphores or whatever else you like.  It is still a timer.   

Timer: a *time* based event that, after a defined amount of time (duh), does an action. (we can have blocking ones like sleep, or multithreaded based ones, like a cron job or an "onTimer()" event).

Push based implementation has a loop in its own thread which asks repetitively to the driver if it is ready to receive a new buffer (which is also related to the previous buffer going to be played).

What you are describing in the second quote is a specific instance of what you define in the first quote. 

Else, I live in a parallel world and I apologise for not knowing that I am there.

I think you just don't understand the concept. 

Re: Foobar event/push mode

Reply #24
I'm gonna stop here.
I am not convinced, but it seems i don't have the strength to make my point stand.

As for this....
Timer: a *time* based event that, after a defined amount of time (duh), does an action. (we can have blocking ones like sleep, or multithreaded based ones, like a cron job or an "onTimer()" event).

Push based implementation has a loop in its own thread which asks repetitively to the driver if it is ready to receive a new buffer (which is also related to the previous buffer going to be played).

What you are describing in the second quote is a specific instance of what you define in the first quote. 

...the second quote is not talking about semaphores. It is the description of a busy loop. You can only make a connection with a timer given that you put the precondition that the data served is controlled by a crystal clock. And there, you have the timer, NOT in the methodology used.

I don't know if you both realize that with your points, the "event based" and the "push based" API become both different timer implementations, so blurring any difference by means of "abstract concepts".