diff options
Diffstat (limited to 'apps/misc.c')
-rw-r--r-- | apps/misc.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/apps/misc.c b/apps/misc.c index fd840749cb..e10fceb9af 100644 --- a/apps/misc.c +++ b/apps/misc.c | |||
@@ -824,6 +824,113 @@ void setvol(void) | |||
824 | settings_save(); | 824 | settings_save(); |
825 | } | 825 | } |
826 | 826 | ||
827 | #ifdef HAVE_PERCEPTUAL_VOLUME | ||
828 | static short norm_tab[MAX_NORM_VOLUME_STEPS+2]; | ||
829 | static int norm_tab_num_steps; | ||
830 | static int norm_tab_size; | ||
831 | |||
832 | static void update_norm_tab(void) | ||
833 | { | ||
834 | const int lim = global_settings.volume_adjust_norm_steps; | ||
835 | if (lim == norm_tab_num_steps) | ||
836 | return; | ||
837 | norm_tab_num_steps = lim; | ||
838 | |||
839 | const int min = sound_min(SOUND_VOLUME); | ||
840 | const int max = sound_max(SOUND_VOLUME); | ||
841 | const int step = sound_steps(SOUND_VOLUME); | ||
842 | |||
843 | /* Ensure the table contains the minimum volume */ | ||
844 | norm_tab[0] = min; | ||
845 | norm_tab_size = 1; | ||
846 | |||
847 | for (int i = 0; i < lim; ++i) | ||
848 | { | ||
849 | int vol = from_normalized_volume(i, min, max, lim); | ||
850 | int rem = vol % step; | ||
851 | |||
852 | vol -= rem; | ||
853 | if (abs(rem) > step/2) | ||
854 | vol += rem < 0 ? -step : step; | ||
855 | |||
856 | /* Add volume step, ignoring any duplicate entries that may | ||
857 | * occur due to rounding */ | ||
858 | if (vol != norm_tab[norm_tab_size-1]) | ||
859 | norm_tab[norm_tab_size++] = vol; | ||
860 | } | ||
861 | |||
862 | /* Ensure the table contains the maximum volume */ | ||
863 | if (norm_tab[norm_tab_size-1] != max) | ||
864 | norm_tab[norm_tab_size++] = max; | ||
865 | } | ||
866 | |||
867 | void set_normalized_volume(int vol) | ||
868 | { | ||
869 | update_norm_tab(); | ||
870 | |||
871 | if (vol < 0) | ||
872 | vol = 0; | ||
873 | if (vol >= norm_tab_size) | ||
874 | vol = norm_tab_size - 1; | ||
875 | |||
876 | global_settings.volume = norm_tab[vol]; | ||
877 | } | ||
878 | |||
879 | int get_normalized_volume(void) | ||
880 | { | ||
881 | update_norm_tab(); | ||
882 | |||
883 | int a = 0, b = norm_tab_size - 1; | ||
884 | while (a != b) | ||
885 | { | ||
886 | int i = (a + b + 1) / 2; | ||
887 | if (global_settings.volume < norm_tab[i]) | ||
888 | b = i - 1; | ||
889 | else | ||
890 | a = i; | ||
891 | } | ||
892 | |||
893 | return a; | ||
894 | } | ||
895 | #else | ||
896 | void set_normalized_volume(int vol) | ||
897 | { | ||
898 | global_settings.volume = vol * sound_steps(SOUND_VOLUME); | ||
899 | } | ||
900 | |||
901 | int get_normalized_volume(void) | ||
902 | { | ||
903 | return global_settings.volume / sound_steps(SOUND_VOLUME); | ||
904 | } | ||
905 | #endif | ||
906 | |||
907 | void adjust_volume(int steps) | ||
908 | { | ||
909 | #ifdef HAVE_PERCEPTUAL_VOLUME | ||
910 | adjust_volume_ex(steps, global_settings.volume_adjust_mode); | ||
911 | #else | ||
912 | adjust_volume_ex(steps, VOLUME_ADJUST_DIRECT); | ||
913 | #endif | ||
914 | } | ||
915 | |||
916 | void adjust_volume_ex(int steps, enum volume_adjust_mode mode) | ||
917 | { | ||
918 | switch (mode) | ||
919 | { | ||
920 | case VOLUME_ADJUST_PERCEPTUAL: | ||
921 | #ifdef HAVE_PERCEPTUAL_VOLUME | ||
922 | set_normalized_volume(get_normalized_volume() + steps); | ||
923 | break; | ||
924 | #endif | ||
925 | case VOLUME_ADJUST_DIRECT: | ||
926 | default: | ||
927 | global_settings.volume += steps * sound_steps(SOUND_VOLUME); | ||
928 | break; | ||
929 | } | ||
930 | |||
931 | setvol(); | ||
932 | } | ||
933 | |||
827 | char* strrsplt(char* str, int c) | 934 | char* strrsplt(char* str, int c) |
828 | { | 935 | { |
829 | char* s = strrchr(str, c); | 936 | char* s = strrchr(str, c); |