May 24, 2009, 10:26 pm
People using IPhone may be impressed by its volume ramping feature. E.g. a telephone call comes in while you are listening to music, the music is gradually volume down until not heard, and then ringtone starts; and after the call is ended, the music is gradually volumed up to the previous level. It is cool, and the user experience is very good!
Our audio manager will also provide this functionality to enhance user experience while audio manager decides to mute/pause some audio streams.
This blog is to introduce how we are going to enable volume ramping feature. And this feature is under development by the time this blog is written. If you have questions you can contact Zheng, Huan (
) and Guo, Jia (
How We Do That
To achieve volume ramping effect of duration X seconds, we need to apply attenuate/amplify factors to a chunk of audio data which is of X seconds long. And the value of the factor changes gradually according to time.
To get the factor, we will use the current existing envelop inside PA and fix its bugs. (3 bugs of envelop.c have been found and 2 of them are calculation overflow). Current PA envelop supports a maximum of 4 points, so it could provide a similar ADSR envelope (http://en.wikipedia.org/wiki/ADSR_envelope). But we will only use 2 points to get linear factor. Below is a picture which depicts how we get linear factor, it's simple and efficient and enough for us to get ramping effect.
The calculation formula is:
y3 = y1 + ((y2 - y1) * (x2 - x1)) / (x3 - x1)
The code of PA that deals with volume and mix does not consider volume ramping at all, and code on this aspect is not modulized, we will need to change the logic of pa_sink_input_peek and pa_mix and possibly some other places to make volume ramping work. Current logic is complex, what we are doing is like adding a gear into a running engine, so we need to spend a lot of time on this aspect.
Our Final Target
Introduce 2 new API to PA module developers inside PA to support volume ramping.
1,void pa_sink_input_set_volume_with_ramping (pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute, pa_usec_t duration);
2,void pa_sink_input_set_mute_with_ramping (pa_sink_input *i, pa_bool_t mute, pa_bool_t save, pa_usec_t duration);
duration is in milliseconds, E.g. 5000 means ramping duration is 5 seconds.
By the time volume ramping is enabled, when AM decides to mute some audio streams, it will mute with ramping, so the user experience may be better. And we may consider to add a configuration item to let app choose whether to be muted with ramping or just directly mute.
And if maintainer agrees, we will export this feature to standard PA APIs, so that all PA developers could use this feature to enhance audio effect.