nnmshckr / soundflower

Automatically exported from code.google.com/p/soundflower
GNU General Public License v2.0
0 stars 0 forks source link

Volume control in SoundFlower (bug and patch) #108

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Hi there,

I have found a bug (or perhaps unfinished feature) in Soundflower regarding the 
volume/gain adjustment. Currently the volume/gain adjustment is linear. So 
whatever the system reports as the value from 0-65535 is the value Soundflower 
is multiplying by (of course after dividing by the max). Soundflower is 
reporting to the OS however that it has a 72 dB volume/gain range, which is not 
actually the case. In the Audio/MIDI setup, you will see that the slider values 
correspond to decibels, however, this is not the actual adjustment being made.

This drastically reduces the ability of a user to adjust the volume because the 
smallest notch is 0.0625 which only corresponds to -24 dB before it goes to 
mute. Furthermore, at the loud end, there is very little difference between 
notches at the top (only 0.5 dB).

I have written a patch that solves this problem by correctly calculating 
gain/volume values in dB. Furthermore, the dynamic range can be specified in 
the code via a single constant per gain (input) and volume (output). I can see 
that the original code was based on the Apple sample code, and the gain 
actually had a positive dB value. In reality, for Soundflower's purpose, the 
input should probably not have actual gain, rather "trim". In essence this is 
the same as the volume code, in that it takes a fraction of the value, and 
never amplifies it.

Attached are the SoundflowerEngine.* and SoundflowerDevice.* files in the 
"code" zip. I have also provided the corresponding patch files if that would be 
more useful to you, in the "patch" zip.

Also of note: on my system, when I calculated the exponential (for the decibel 
formula), I first tried using math.h, however it resulted in the extension 
crashing. Because of this, I opted for using a simple Taylor series recursion 
function to calculate the exponential, and that allowed me to not have to 
include anything else.

Finally, I increased the nominal dynamic range to 96 dB (but this could be 
changed or go in the plist). This corresponds to an effective range of 72 dB 
because that bottom notch on volume control is "mute". Note that the values the 
OS reports in Audio MIDI setup are correct for dB, however the normalized 
"Value" is not linear. It's some weird non-linear, non-exponential curve Apple 
came up with which basically causes ca. 3 dB of attenuation/step for the upper 
10 steps, and then an exponential round out towards the bottom. I couldn't find 
any reference or explanation for this, but basically the effect is that it 
gives finer volume control near the top. Mac OS X does know the actual linear 
value of the volume and the corresponding dB, and that is what this patch 
addresses--to make those things correspond. If you use a sound editor and put 
out a tone at 0 dB to the Soundflower bus, then the dB reported in Audio MIDI 
Setup will be the level that it records at on the bus.

Let me know if you have any questions about my implementation. I hacked this 
out in 3 hours, so it's new to me too...

All the best,

Andrew

---
William Andrew Burnson, doctoral student
School of Music, University of Illinois
http://williamandrewburnson.com

Original issue reported on code.google.com by William....@gmail.com on 11 Aug 2011 at 1:26

Attachments:

GoogleCodeExporter commented 8 years ago
I just happened across this repository by accident while looking for updates to 
a lion issue. Incidentally, there are other forks of this project. I 
contributed a very similar patch to yours to one of the forks quite a while 
ago. It's been integrated into that code base: 
https://github.com/tap/Soundflower

I didn't realize at the time that this was the original repository. Oops. :/

Original comment by alexan...@hudek.org on 12 Aug 2011 at 4:11

GoogleCodeExporter commented 8 years ago
Andrew,

I've been looking for a solution exactly like the one you've provided!  I'm 
fairly new to the OS X environment and not at all familiar with scripting, so 
I'm not too sure how to apply the patch that you've created.  Would you be able 
to guide me a little bit further?

Thank you in advance,

Robert Lynch

Original comment by rjly...@gmail.com on 17 Aug 2011 at 12:58

GoogleCodeExporter commented 8 years ago
Robert,

You could try following the instructions in the git repository I posted above, 
it has a simliar patch integrated. My patch differs a bit, I didn't use a 
taylor series to approximate log, but rather embedded a lookup table. This is 
far better for CPU usage with the negative that it has less resolution when 
adjusting the volume. However, for all practical purposes, you won't notice the 
lack of resolution. It would manifest itself as little steps when you slide the 
volume slider. It's fine enough that I can't hear anything.

Alex

Original comment by alexan...@hudek.org on 25 Aug 2011 at 8:50

GoogleCodeExporter commented 8 years ago
IMO the real negative is that you can't adjust the dynamic range of the volume 
control with a fixed lookup table (if you're going to go to the trouble to 
build it yourself, might as well have the dynamic range you want). I don't know 
that it is really "far better" for CPU usage in that this thing is calculated 
outside the inner loop twice per buffer length, not per sample. If it is really 
an issue, you could easily just calculate the exponential when the volume 
changes, but I really think it's in the noise. I didn't bother to optimize 
since the inner loop is a wreck with an unnecessary if-else, and index 
calculation. (Not sure if GCC will optimize away all of that).

Original comment by William....@gmail.com on 25 Aug 2011 at 6:07

GoogleCodeExporter commented 8 years ago
Yep, all good points. I didn't realize you were computing it only once per 
buffer, it's probably not a big deal.  You could also compute a fixed table on 
initialization. My solution was based on habit. :)  It would also be neat to be 
able to adjust the dynamic range via a configuration panel somewhere. Something 
to consider for later I guess. 

A better question, is this repo still taking updates? The last source change 
was in 2010. It may be time for a fork, or to switch to the git version. I'm 
not entirely sure that tap is still watching the git repository either. A pull 
request has been sitting there since aug. 13.

Original comment by alexan...@hudek.org on 29 Aug 2011 at 8:04

GoogleCodeExporter commented 8 years ago
I do not know if the repo is taking updates. tap is active on other projects. 
We could contact the user and see if either someone could be added as admin, or 
simply switch to github.

And yes, I agree there should be a config panel, and the settings should be 
stored in its Info.plist (which already has information there regarding the 
number of channels, supported sample rates, etc.)

Original comment by William....@gmail.com on 31 Aug 2011 at 8:28

GoogleCodeExporter commented 8 years ago
I have to agree with the original poster, this is definitely an issue with the 
latest release. I took his patch and recompile the driver. Works a lot better 
now, especially on the full volume side, on the low volume side however it goes 
quiet a lot sooner. (maybe around 40% so maybe it sorta flipped)

Original comment by erik.kri...@gmail.com on 1 Oct 2011 at 4:15

GoogleCodeExporter commented 8 years ago
Hi :) 

I'm having the same problem. Unfortunately, like Robert, I really have no idea 
how to integrate these patches :( Any suggestions? Or a step by step solution 
perhaps?

Thanks!
Nat

Original comment by n...@renyi.net on 3 Oct 2011 at 10:40

GoogleCodeExporter commented 8 years ago
Hi!

For integrating patches etc. it is definitely better to use Github.  This 
repository / project is still here because it existed first, and I still try to 
sync this to Github from time to time, but I'm working out of Github for the 
most part.

Also, my work on this is a kind of side project at Cycling '74.  In 2011 we 
released Max 6 and it required that all resources be focused on that task.  It 
would be fabulous if there were some others helping to improve Soundflower and 
keep it alive when I'm sucked away on other projects that are actually paying 
the bills!

I'd like to publish a new installer soon to get some of the additions since the 
2010 release.  So please hop in or send me a note on Github if you'd like get 
something into this update.

Thanks!

Original comment by t...@electrotap.com on 1 Feb 2012 at 4:53