2) Setting the volume. I can send VolUp and VolDown IR codes, but that's yucky. There might be an ioctl() somewhere for me to set it, but I'd have to set it as a percentage of the current volume, or relative to some baseline volume or something... Maybe re-use something that was provided with the volume boost stuff? Not sure if there were userland hooks to that stuff or not.
arch/arm/special/empeg_mixer.c contains the volume ioctls (both read and write) that the player uses. If you use these, then the volume_boost code will continue to work transparently in the kernel.
The big question is really whether you try to attempt absolute or relative volumes...
Absolute values can be found by looking at
volume_entry volume_table[101] in empeg_mixer.c. Notice that 0dB corresponds to the 90th row. But I can't see how to make absolute values work - people would want to change their volumes anyway.
Relative values would suffer from the same issue that the volboost code suffers from - the volume steps aren't a consistent size across the whole volume range. In practice I think that this gives acceptable results though since most people will use their empegs in the linear region.
You will obviously need to do something similar to the volboost code and keep tabs on what adjustment you are making at any time, and removing the current adjustment before re-reading the volume (in case the user changed it mid-song) and applying the new one. This keeping tabs is made harder by the fact that any adjustment you make has to be kept within the hard limits of 0 <= adj <= 100. You'll have to detect when this happens and calculate what adjustment you *really* make in order to be able to undo it;
Assuming that you'd call this after reading the ID3 tags for a new track...sorry about the lazy syntax;
int current_adjust =0; // initialised globally
volume_change() {
// remove previous adjustment first.
vol = read_vol();
vol = vol - current_adjust; //current_adjust = 0 first time.
write_vol(vol);
if (ID3_vol_tag) {
vol = vol + ID3_vol_tag;
if (vol > 100) {
// Hit limit - have to calculate real adjusment.
current_adjust = vol - 100;
vol = 100;
}
else
if (vol < 0) {
// hit the other limit...
current_adjust = ( 0 - ( vol - ID3_vol_tag));
vol = 0;
}
else {
current_adjust = ID3_vol_tag; }
write_vol(vol);
}
The other thing you want to consider is whether to cap at 90 (0dB) or not. You could read the users current cap setting in config.ini.
On the one hand, capping at 90 will still leave headroom for the volboost code, although this isn't really a factor since most people don't boost in mp3 playback (although they *could* if they really wanted!). On the other hand, if people are listening at a loud level then the ID3 based tag could run out of headroom. I suspect that the best thing to do is to cap at 100.