First: I apologize for the title, I truly don't know what the correct terms to describe my problem are. If I receive suggestions for a more appropriate title or learn some new terms I will revise it.

I am working on a formula (in Excel) that will control the volume level that is restored when a user un-pauses an audio player. Rather than restore to 100% of the previous volume I want to restore to a percentage of the previous level based on two criteria:

  1. Previous volume % of max volume (zero previous volume has no effect, full volume would reduce restored volume by 20%. You can see this in the below formula as 0.2 / 120)
  2. Duration paused within a 0-10 minute scale (0 minutes = 100% restore, 10 minutes = 50%)

I always want to restore volume to a minimum of 50% of the previous level and this is where my current formula is failing me. My current formula looks like this:

Volume = 1 - ((0.5 / 10) * pausedDuration)      -  ((0.2 / 120) * lastVolume)
             [ reduce based on pause duration ]    [ reduce by last vol. level ]

If pausedDuration is 10 and lastVolume is 120, Volume will be .3 (30%) which is below my 50% minimum. I understand why this happens but I don't know how to structure my formula to correct it.

If pauseDuration is 0 and lastVolume is 120, Volume will be .8 (80%). This is because the pauseDuration is having no reduction in restore levels but the volume was maxed out which reduced the restore volume by 20%. If the lastVolume had been 50 the restore level would be 0.916 (91.6%)

I don't want to simply clamp the value with a MAX() function as that will result in a flat output when the minimum is reach and I want a linear scale across the entire range. I'm starting suspect this needs to be broken up into two calculations: first the percentage from

My question: How can I have two values on their own scales combine to reduce a value by 0 - 0.5?

Update: I thought about breaking this calculation up to better illustrate what I'm trying to achieve and I was able to make it work as two calculations.

Working Google Spreadsheet for experimentation (change the two light blue cells to see the calculation)

Pseudo code/formula:

First calculate the pause duration adjustment (0-50%)
  adj1 = (0.5 / 10) * pausedDuration

Next calculate the additional volume level adjustment relative to the pause duration adjustment
  adj2 = (0.5 - adj1) / 0.5 * ((0.2 / 120) * lastVolume)

Finally you have the total restore offset
  volume = 1.0 - adj2

Now that is one convoluted and ugly calculation! Now that I have a working example I'm hoping someone can suggest an elegant way to accomplish the same result.



Vol = (0.5 + 0.5 * ( pausedDuration/10)) * lastVolume

Notice that the thing in the large parens is always at least 0.5, so you'll always get at least 0.5*lastVolume; the thing in the large parens is also always at most 1.0, so you'll never get more than 1.0*lastVolume. (This assumes that pausedDuration is clamped at 10, of course.)

=== Now that I've seen your larger explanation, I think that your final code has all the right ingredients. The last line should be vol = 1 - (adj1 + adj2), but otherwise it's OK.

Let me see if I have the facts straight:

  • The "volume" goes from 0 (min) to 120 (max)

  • pauseDuration goes from 0 to 10

You want to come out with a number between 0 and 1 representing a percentage, I guess, and you'll multiply it by 120 to get an actual volume.

I'd do this:

adj1 = lastVolume/120;    // ranges from 0 to 1
adj2 = pauseDuration/10;  // ranges from 0 to 1

You now want to apply adjustment 1, and if there's any room left over, apply adjustment 2. (At least that's what your code above did). That is

reduction = adj1 * 0.5 + (1 - adj1) * adj2 * 0.2;
volFraction = 1 - reduction;
newVolume = volFraction * lastVolume;

That's not quite symmetric in the reductions (i.e., the "50%" reduction affects the 20% one, but not the other way around), but it works pretty decently.

I can't really call this an answer, since it's more or less the thing you wrote, but slightly polished up. But I hope it helps regardless.

  • $\begingroup$ Are you missing an operator between the second 0.5 and the first set of ()? I tried assuming multiplication but the result is not what I would expect. Also looking at this, unless it's flying right over my head, I don't see how this takes into considering the 20% adjustment for last volume. From your reputation I'm thinking I'm missing something ;) $\endgroup$ – Steve K Mar 23 '15 at 15:56
  • $\begingroup$ 1. Yes, I was missing a "*"...call it "pseudocode" (or "bad pseudocode"). I've fixed it. 2. I didn't see an explanation of the "20%"; I just saw a random 0.2 and 120 in your formula, and figured they were attempts to compensate for what was going wrong with the "50%" thing. If you can enlarge your explanation with a few more instances (like "if you pause then restart instantly, so that "pausedDuration" is essentially zero, the newVolume should be XYY; if you pause 10 min, it should be PQR") then maybe I can help further. $\endgroup$ – John Hughes Mar 23 '15 at 17:57
  • $\begingroup$ OK, I figured that's what you meant but wanted to confirm. I understand the problem isn't clear and that's my fault. I've tried to clarify but I'm not sure if it's helped. Essentially I have two calculations that are reducing the restored volume from 100%. These calculations when both are used can't result in > 50% reduction. $\endgroup$ – Steve K Mar 23 '15 at 19:23
  • $\begingroup$ I've added some more material; hope it's of some help. $\endgroup$ – John Hughes Mar 23 '15 at 21:48
  • $\begingroup$ Hi John, thank you for the additional details and polishing. Your comment "That's not quite symmetric in the reductions" is valid and interesting, I would be very interested in a suggested alternate formula if you have anything in mind? $\endgroup$ – Steve K Mar 24 '15 at 20:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.