diff --git a/app/src/main/java/com/grarak/kerneladiutor/fragments/kernel/SoundFragment.java b/app/src/main/java/com/grarak/kerneladiutor/fragments/kernel/SoundFragment.java index c0324b5ea..e51a01874 100755 --- a/app/src/main/java/com/grarak/kerneladiutor/fragments/kernel/SoundFragment.java +++ b/app/src/main/java/com/grarak/kerneladiutor/fragments/kernel/SoundFragment.java @@ -22,7 +22,9 @@ import com.grarak.kerneladiutor.R; import com.grarak.kerneladiutor.fragments.ApplyOnBootFragment; import com.grarak.kerneladiutor.fragments.RecyclerViewFragment; +import com.grarak.kerneladiutor.utils.Prefs; import com.grarak.kerneladiutor.utils.kernel.sound.Sound; +import com.grarak.kerneladiutor.views.recyclerview.CardView; import com.grarak.kerneladiutor.views.recyclerview.RecyclerViewItem; import com.grarak.kerneladiutor.views.recyclerview.SeekBarView; import com.grarak.kerneladiutor.views.recyclerview.SwitchView; @@ -52,18 +54,18 @@ protected void addItems(List items) { if (Sound.hasHeadphoneGain()) { headphoneGainInit(items); } + if (Sound.hasHeadphonePowerAmpGain()) { + headphonePowerAmpGainInit(items); + } + if (Sound.hasSpeakerGain()) { + speakerGainInit(items); + } if (Sound.hasHandsetMicrophoneGain()) { handsetMicrophoneGainInit(items); } if (Sound.hasCamMicrophoneGain()) { camMicrophoneGainInit(items); } - if (Sound.hasSpeakerGain()) { - speakerGainInit(items); - } - if (Sound.hasHeadphonePowerAmpGain()) { - headphonePowerAmpGainInit(items); - } if (Sound.hasHeadphoneTpaGain()) { headphoneTpaGainInit(items); } @@ -109,15 +111,40 @@ public void onChanged(SwitchView switchView, boolean isChecked) { items.add(highPerfMode); } + // ------------ + // This method's layout will also be used for speakerGainInit() and headphonePowerAmpGainInit(). + // The comments won't be repeated. + // ------------ private void headphoneGainInit(List items) { - SeekBarView headphoneGain = new SeekBarView(); - headphoneGain.setTitle(getString(R.string.headphone_gain)); + // Note: All RecyclerViewItems are declared as final so they can be accessed + // by the SeekBarManager class declared below. + + // Create a CardView and add our stuff to it. + final CardView hpGainCard = new CardView(getActivity()); + hpGainCard.setTitle(getString(R.string.headphone_gain)); + + // Set this boolean to false if it doesn't exist + if (!(Prefs.getBoolean("fauxsound_perchannel_headphone_gain", false, getActivity()))) + Prefs.saveBoolean("fauxsound_perchannel_headphone_gain", false, getActivity()); + + // Now create our SwitchView to toggle per-channel controls. + // We won't add a OnSwitchListener to it yet. But add it to hpGainCard anyway. + final SwitchView perChannel = new SwitchView(); + perChannel.setTitle(getString(R.string.per_channel_controls)); + perChannel.setSummary(getString(R.string.per_channel_controls_summary)); + perChannel.setChecked(Prefs.getBoolean("fauxsound_perchannel_headphone_gain", false, getActivity())); + hpGainCard.addItem(perChannel); + + // We'll have three different SeekBarViews. + // This seekbar will control gain for all channels. + final SeekBarView headphoneGain = new SeekBarView(); + headphoneGain.setTitle(getString(R.string.all_channels)); headphoneGain.setItems(Sound.getHeadphoneGainLimits()); - headphoneGain.setProgress(Sound.getHeadphoneGainLimits().indexOf(Sound.getHeadphoneGain())); + headphoneGain.setProgress(Sound.getHeadphoneGainLimits().indexOf(Sound.getHeadphoneGain("all"))); headphoneGain.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() { @Override public void onStop(SeekBarView seekBarView, int position, String value) { - Sound.setHeadphoneGain(value, getActivity()); + Sound.setHeadphoneGain("all", value, getActivity()); } @Override @@ -125,7 +152,74 @@ public void onMove(SeekBarView seekBarView, int position, String value) { } }); - items.add(headphoneGain); + // This seekbar will control gain for the left channel only. + final SeekBarView headphoneGainLeft = new SeekBarView(); + headphoneGainLeft.setTitle(getString(R.string.left_channel)); + headphoneGainLeft.setItems(Sound.getHeadphoneGainLimits()); + headphoneGainLeft.setProgress(Sound.getHeadphoneGainLimits().indexOf(Sound.getHeadphoneGain("left"))); + headphoneGainLeft.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() { + @Override + public void onStop(SeekBarView seekBarView, int position, String value) { + Sound.setHeadphoneGain("left", value, getActivity()); + } + + @Override + public void onMove(SeekBarView seekBarView, int position, String value) { + } + }); + + // This seekbar will control gain for the right channel only. + final SeekBarView headphoneGainRight = new SeekBarView(); + headphoneGainRight.setTitle(getString(R.string.right_channel)); + headphoneGainRight.setItems(Sound.getHeadphoneGainLimits()); + headphoneGainRight.setProgress(Sound.getHeadphoneGainLimits().indexOf(Sound.getHeadphoneGain("right"))); + headphoneGainRight.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() { + @Override + public void onStop(SeekBarView seekBarView, int position, String value) { + Sound.setHeadphoneGain("right", value, getActivity()); + } + + @Override + public void onMove(SeekBarView seekBarView, int position, String value) { + } + }); + + // This class will show or hide the seekbars according to perChannel's state + class SeekBarManager { + public void showPerChannelSeekbars (boolean enable) { + if (enable == true) { + hpGainCard.removeItem(headphoneGain); + hpGainCard.addItem(headphoneGainLeft); + hpGainCard.addItem(headphoneGainRight); + } else { + hpGainCard.removeItem(headphoneGainLeft); + hpGainCard.removeItem(headphoneGainRight); + hpGainCard.addItem(headphoneGain); + } + } + } + + // Create a new instance of SeekBarManager + final SeekBarManager manager = new SeekBarManager(); + + // Call the newly-instantiated SeekBarManager above + if (Prefs.getBoolean("fauxsound_perchannel_headphone_gain", false, getActivity()) == true) { + manager.showPerChannelSeekbars(true); + } else { + manager.showPerChannelSeekbars(false); + } + + // Now we'll add the OnSwitchListener to perChannel. + perChannel.addOnSwitchListener(new SwitchView.OnSwitchListener() { + @Override + public void onChanged(SwitchView switchview, boolean isChecked) { + Prefs.saveBoolean("fauxsound_perchannel_headphone_gain", isChecked, getActivity()); + manager.showPerChannelSeekbars(isChecked); + } + }); + + // Now add the CardView with all its items to our main List + items.add(hpGainCard); } private void handsetMicrophoneGainInit(List items) { @@ -168,14 +262,41 @@ public void onMove(SeekBarView seekBarView, int position, String value) { } private void speakerGainInit(List items) { - SeekBarView speakerGain = new SeekBarView(); - speakerGain.setTitle(getString(R.string.speaker_gain)); + final CardView speakerGainCard = new CardView(getActivity()); + speakerGainCard.setTitle(getString(R.string.speaker_gain)); + + if (!(Prefs.getBoolean("fauxsound_perchannel_speaker_gain", false, getActivity()))) + Prefs.saveBoolean("fauxsound_perchannel_speaker_gain", false, getActivity()); + + final SwitchView perChannel = new SwitchView(); + perChannel.setTitle(getString(R.string.per_channel_controls)); + perChannel.setSummary(getString(R.string.per_channel_controls_summary)); + perChannel.setChecked(Prefs.getBoolean("fauxsound_perchannel_speaker_gain", false, getActivity())); + speakerGainCard.addItem(perChannel); + + final SeekBarView speakerGain = new SeekBarView(); + speakerGain.setTitle(getString(R.string.all_channels)); speakerGain.setItems(Sound.getSpeakerGainLimits()); - speakerGain.setProgress(Sound.getSpeakerGainLimits().indexOf(Sound.getSpeakerGain())); + speakerGain.setProgress(Sound.getSpeakerGainLimits().indexOf(Sound.getSpeakerGain("all"))); speakerGain.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() { @Override public void onStop(SeekBarView seekBarView, int position, String value) { - Sound.setSpeakerGain(value, getActivity()); + Sound.setSpeakerGain("all", value, getActivity()); + } + + @Override + public void onMove(SeekBarView seekBarView, int position, String value) { + } + }); + + final SeekBarView speakerGainLeft = new SeekBarView(); + speakerGainLeft.setTitle(getString(R.string.left_channel)); + speakerGainLeft.setItems(Sound.getSpeakerGainLimits()); + speakerGainLeft.setProgress(Sound.getSpeakerGainLimits().indexOf(Sound.getSpeakerGain("left"))); + speakerGainLeft.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() { + @Override + public void onStop(SeekBarView seekBarView, int position, String value) { + Sound.setSpeakerGain("left", value, getActivity()); } @Override @@ -183,19 +304,75 @@ public void onMove(SeekBarView seekBarView, int position, String value) { } }); - items.add(speakerGain); + final SeekBarView speakerGainRight = new SeekBarView(); + speakerGainRight.setTitle(getString(R.string.right_channel)); + speakerGainRight.setItems(Sound.getSpeakerGainLimits()); + speakerGainRight.setProgress(Sound.getSpeakerGainLimits().indexOf(Sound.getSpeakerGain("right"))); + speakerGainRight.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() { + @Override + public void onStop(SeekBarView seekBarView, int position, String value) { + Sound.setSpeakerGain("right", value, getActivity()); + } + + @Override + public void onMove(SeekBarView seekBarView, int position, String value) { + } + }); + + class SeekBarManager { + public void showPerChannelSeekbars (boolean enable) { + if (enable == true) { + speakerGainCard.removeItem(speakerGain); + speakerGainCard.addItem(speakerGainLeft); + speakerGainCard.addItem(speakerGainRight); + } else { + speakerGainCard.removeItem(speakerGainLeft); + speakerGainCard.removeItem(speakerGainRight); + speakerGainCard.addItem(speakerGain); + } + } + } + + final SeekBarManager manager = new SeekBarManager(); + + if (Prefs.getBoolean("fauxsound_perchannel_speaker_gain", false, getActivity()) == true) { + manager.showPerChannelSeekbars(true); + } else { + manager.showPerChannelSeekbars(false); + } + + perChannel.addOnSwitchListener(new SwitchView.OnSwitchListener() { + @Override + public void onChanged(SwitchView switchview, boolean isChecked) { + Prefs.saveBoolean("fauxsound_perchannel_speaker_gain", isChecked, getActivity()); + manager.showPerChannelSeekbars(isChecked); + } + }); + + items.add(speakerGainCard); } private void headphonePowerAmpGainInit(List items) { - SeekBarView headphonePowerAmpGain = new SeekBarView(); - headphonePowerAmpGain.setTitle(getString(R.string.headphone_poweramp_gain)); - headphonePowerAmpGain.setItems(Sound.getHeadphonePowerAmpGainLimits()); - headphonePowerAmpGain.setProgress(Sound.getHeadphonePowerAmpGainLimits() - .indexOf(Sound.getHeadphonePowerAmpGain())); - headphonePowerAmpGain.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() { + final CardView hpPAGainCard = new CardView(getActivity()); + hpPAGainCard.setTitle(getString(R.string.headphone_poweramp_gain)); + + if (!(Prefs.getBoolean("fauxsound_perchannel_headphone_pa_gain", false, getActivity()))) + Prefs.saveBoolean("fauxsound_perchannel_headphone_pa_gain", false, getActivity()); + + final SwitchView perChannel = new SwitchView(); + perChannel.setTitle(getString(R.string.per_channel_controls)); + perChannel.setSummary(getString(R.string.per_channel_controls_summary)); + perChannel.setChecked(Prefs.getBoolean("fauxsound_perchannel_headphone_pa_gain", false, getActivity())); + hpPAGainCard.addItem(perChannel); + + final SeekBarView headphonePAGain = new SeekBarView(); + headphonePAGain.setTitle(getString(R.string.all_channels)); + headphonePAGain.setItems(Sound.getHeadphonePowerAmpGainLimits()); + headphonePAGain.setProgress(Sound.getHeadphonePowerAmpGainLimits().indexOf(Sound.getHeadphonePowerAmpGain("all"))); + headphonePAGain.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() { @Override public void onStop(SeekBarView seekBarView, int position, String value) { - Sound.setHeadphonePowerAmpGain(value, getActivity()); + Sound.setHeadphonePowerAmpGain("all", value, getActivity()); } @Override @@ -203,7 +380,70 @@ public void onMove(SeekBarView seekBarView, int position, String value) { } }); - items.add(headphonePowerAmpGain); + final SeekBarView headphonePAGainLeft = new SeekBarView(); + headphonePAGainLeft.setTitle(getString(R.string.left_channel)); + headphonePAGainLeft.setItems(Sound.getHeadphonePowerAmpGainLimits()); + headphonePAGainLeft.setProgress(Sound.getHeadphonePowerAmpGainLimits().indexOf(Sound.getHeadphonePowerAmpGain("left"))); + headphonePAGainLeft.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() { + @Override + public void onStop(SeekBarView seekBarView, int position, String value) { + Sound.setHeadphonePowerAmpGain("left", value, getActivity()); + } + + @Override + public void onMove(SeekBarView seekBarView, int position, String value) { + } + }); + + final SeekBarView headphonePAGainRight = new SeekBarView(); + headphonePAGainRight.setTitle(getString(R.string.right_channel)); + headphonePAGainRight.setItems(Sound.getHeadphonePowerAmpGainLimits()); + headphonePAGainRight.setProgress(Sound.getHeadphonePowerAmpGainLimits().indexOf(Sound.getHeadphonePowerAmpGain("right"))); + headphonePAGainRight.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() { + @Override + public void onStop(SeekBarView seekBarView, int position, String value) { + Sound.setHeadphonePowerAmpGain("right", value, getActivity()); + } + + @Override + public void onMove(SeekBarView seekBarView, int position, String value) { + } + }); + + class SeekBarManager { + public void showPerChannelSeekbars (boolean enable) { + if (enable == true) { + hpPAGainCard.removeItem(headphonePAGain); + hpPAGainCard.addItem(headphonePAGainLeft); + hpPAGainCard.addItem(headphonePAGainRight); + } else { + hpPAGainCard.removeItem(headphonePAGainLeft); + hpPAGainCard.removeItem(headphonePAGainRight); + hpPAGainCard.addItem(headphonePAGain); + } + } + } + + final SeekBarManager manager = new SeekBarManager(); + + // Call the newly-instantiated SeekBarManager above + if (Prefs.getBoolean("fauxsound_perchannel_headphone_pa_gain", false, getActivity()) == true) { + manager.showPerChannelSeekbars(true); + } else { + manager.showPerChannelSeekbars(false); + } + + // Now we'll add the OnSwitchListener to perChannel. + perChannel.addOnSwitchListener(new SwitchView.OnSwitchListener() { + @Override + public void onChanged(SwitchView switchview, boolean isChecked) { + Prefs.saveBoolean("fauxsound_perchannel_headphone_pa_gain", isChecked, getActivity()); + manager.showPerChannelSeekbars(isChecked); + } + }); + + // Now add the CardView with all its items to our main List + items.add(hpPAGainCard); } private void headphoneTpaGainInit(List items) { diff --git a/app/src/main/java/com/grarak/kerneladiutor/utils/kernel/sound/Sound.java b/app/src/main/java/com/grarak/kerneladiutor/utils/kernel/sound/Sound.java index 32a4fe695..9fd967276 100755 --- a/app/src/main/java/com/grarak/kerneladiutor/utils/kernel/sound/Sound.java +++ b/app/src/main/java/com/grarak/kerneladiutor/utils/kernel/sound/Sound.java @@ -130,13 +130,20 @@ public static boolean hasLockOutputGain() { return Utils.existFile(LOCK_OUTPUT_GAIN); } - public static void setHeadphonePowerAmpGain(String value, Context context) { - value = String.valueOf(38 - Utils.strToInt(value)); - fauxRun(value + " " + value, HEADPHONE_POWERAMP_GAIN, HEADPHONE_POWERAMP_GAIN, context); - } + public static String getHeadphonePowerAmpGain(String channel) { + String[] values = Utils.readFile(HEADPHONE_POWERAMP_GAIN).split(" "); + String gainLeft = String.valueOf(38 - Utils.strToInt(values[0])), + gainRight = String.valueOf(38 - Utils.strToInt(values[1])); + switch (channel) { + case "all": + case "left": + return gainLeft; + case "right": + return gainRight; + } - public static String getHeadphonePowerAmpGain() { - return String.valueOf(38 - Utils.strToInt(Utils.readFile(HEADPHONE_POWERAMP_GAIN).split(" ")[0])); + // Return a blank string to avoid NPEs + return ""; } public static List getHeadphonePowerAmpGainLimits() { @@ -151,14 +158,21 @@ public static boolean hasHeadphonePowerAmpGain() { return Utils.existFile(HEADPHONE_POWERAMP_GAIN); } - public static void setHeadphoneTpaGain(String value, Context context) { - /* - * Headphone Amp Gain is register 0x7. - * Zero corresponds to 185 (0xb9). The min value is -24 (0xa1) and max is 6 (0xbf). - */ - run(Control.chmod("222", TPA6165_SET_REG), TPA6165_SET_REG, context); - run(Control.write("0x07 0x" + Integer.toHexString(185 + Utils.strToInt(value)), - TPA6165_SET_REG), TPA6165_SET_REG, context); + public static void setHeadphonePowerAmpGain(String channel, String value, Context context) { + value = String.valueOf(38 - Utils.strToInt(value)); + switch (channel) { + case "all": + fauxRun(value + " " + value, HEADPHONE_POWERAMP_GAIN, HEADPHONE_POWERAMP_GAIN, context); + break; + case "left": + String currentGainRight = getHeadphonePowerAmpGain("right"); + fauxRun(value + " " + currentGainRight, HEADPHONE_POWERAMP_GAIN, HEADPHONE_POWERAMP_GAIN, context); + break; + case "right": + String currentGainLeft = getHeadphonePowerAmpGain("left"); + fauxRun(currentGainLeft + " " + value, HEADPHONE_POWERAMP_GAIN, HEADPHONE_POWERAMP_GAIN, context); + break; + } } public static String getHeadphoneTpaGain() { @@ -178,41 +192,48 @@ public static List getHeadphoneTpaGainLimits() { return list; } + public static void setHeadphoneTpaGain(String value, Context context) { + /* + * Headphone Amp Gain is register 0x7. + * Zero corresponds to 185 (0xb9). The min value is -24 (0xa1) and max is 6 (0xbf). + */ + run(Control.chmod("222", TPA6165_SET_REG), TPA6165_SET_REG, context); + run(Control.write("0x07 0x" + Integer.toHexString(185 + Utils.strToInt(value)), + TPA6165_SET_REG), TPA6165_SET_REG, context); + } + public static boolean hasHeadphoneTpaGain() { return Utils.existFile(TPA6165_SET_REG) && Utils.existFile(TPA6165_REGISTERS_LIST); } - public static void setSpeakerGain(String value, Context context) { + public static String getSpeakerGain(String channel) { switch (SPEAKER_GAIN_FILE) { case SPEAKER_GAIN: - int newGain = Utils.strToInt(value); - if (newGain >= 0 && newGain <= 20) { - // Zero / 1 to 20 (positive gain range) - fauxRun(value + " " + value, SPEAKER_GAIN, SPEAKER_GAIN, context); - } else if (newGain <= -1 && newGain >= -30) { - // -1 to -30 (negative gain range) - value = String.valueOf(newGain + 256); - fauxRun(value + " " + value, SPEAKER_GAIN, SPEAKER_GAIN, context); + String[] values = Utils.readFile(SPEAKER_GAIN).split(" "); + int gainLeft = Utils.strToInt(values[0]), + gainRight = Utils.strToInt(values[1]); + switch (channel) { + case "all": + case "left": + if (gainLeft >= 0 && gainLeft <= 20) { + return String.valueOf(gainLeft); + } else if (gainLeft >= 226 && gainLeft <= 255) { + return String.valueOf(gainLeft - 256); + } + break; + case "right": + if (gainRight >= 0 && gainRight <= 20) { + return String.valueOf(gainRight); + } else if (gainRight >= 226 && gainRight <= 255) { + return String.valueOf(gainRight - 256); + } + break; } - case SPEAKER_BOOST: - run(Control.write(value, SPEAKER_BOOST), SPEAKER_BOOST, context); - break; - } - } - public static String getSpeakerGain() { - switch (SPEAKER_GAIN_FILE) { - case SPEAKER_GAIN: - int gain = Utils.strToInt(Utils.readFile(SPEAKER_GAIN).split(" ")[0]); - if (gain >= 0 && gain <= 20) { - return String.valueOf(gain); - } else if (gain >= 226 && gain <= 255) { - return String.valueOf(gain - 256); - } - break; case SPEAKER_BOOST: return Utils.readFile(SPEAKER_BOOST); } + // Return a blank string to avoid NPEs return ""; } @@ -237,6 +258,50 @@ public static boolean hasSpeakerGain() { return SPEAKER_GAIN_FILE != null; } + public static void setSpeakerGain(String channel, String value, Context context) { + switch (SPEAKER_GAIN_FILE) { + case SPEAKER_GAIN: + int newGain = Utils.strToInt(value); + switch (channel) { + case "all": + if (newGain >= 0 && newGain <= 20) { + // Zero / 1 to 20 (positive gain range) + fauxRun(value + " " + value, SPEAKER_GAIN, SPEAKER_GAIN, context); + } else if (newGain <= -1 && newGain >= -30) { + // -1 to -30 (negative gain range) + value = String.valueOf(newGain + 256); + fauxRun(value + " " + value, SPEAKER_GAIN, SPEAKER_GAIN, context); + } + break; + case "left": + String currentGainRight = getSpeakerGain("right"); + if (newGain >= 0 && newGain <= 20) { + // Zero / 1 to 20 (positive gain range) + fauxRun(value + " " + currentGainRight, SPEAKER_GAIN, SPEAKER_GAIN, context); + } else if (newGain <= -1 && newGain >= -30) { + // -1 to -30 (negative gain range) + value = String.valueOf(newGain + 256); + fauxRun(value + " " + currentGainRight, SPEAKER_GAIN, SPEAKER_GAIN, context); + } + break; + case "right": + String currentGainLeft = getSpeakerGain("left"); + if (newGain >= 0 && newGain <= 20) { + // Zero / 1 to 20 (positive gain range) + fauxRun(currentGainLeft + " " + value, SPEAKER_GAIN, SPEAKER_GAIN, context); + } else if (newGain <= -1 && newGain >= -30) { + // -1 to -30 (negative gain range) + value = String.valueOf(newGain + 256); + fauxRun(currentGainLeft + " " + value, SPEAKER_GAIN, SPEAKER_GAIN, context); + } + break; + } + case SPEAKER_BOOST: + run(Control.write(value, SPEAKER_BOOST), SPEAKER_BOOST, context); + break; + } + } + public static void setCamMicrophoneGain(String value, Context context) { int newGain = Utils.strToInt(value); if (newGain >= 0 && newGain <= 20) { @@ -294,24 +359,27 @@ public static boolean hasHandsetMicrophoneGain() { return Utils.existFile(HANDSET_MICROPHONE_GAIN); } - public static void setHeadphoneGain(String value, Context context) { - int newGain = Utils.strToInt(value); - if (newGain >= 0 && newGain <= 20) { - fauxRun(value + " " + value, HEADPHONE_GAIN, HEADPHONE_GAIN, context); - } else if (newGain <= -1 && newGain >= -30) { - value = String.valueOf(newGain + 256); - fauxRun(value + " " + value, HEADPHONE_GAIN, HEADPHONE_GAIN, context); - } - } - - public static String getHeadphoneGain() { - String value = Utils.readFile(HEADPHONE_GAIN); - int gain = Utils.strToInt(value.contains(" ") ? value.split(" ")[0] : value); - if (gain >= 0 && gain <= 20) { - return String.valueOf(gain); - } else if (gain >= 226 && gain <= 255) { - return String.valueOf(gain - 256); + public static String getHeadphoneGain(String channel) { + String[] values = Utils.readFile(HEADPHONE_GAIN).split(" "); + int gainLeft = Utils.strToInt(values[0]), + gainRight = Utils.strToInt(values[1]); + switch (channel) { + case "all": + case "left": + if (gainLeft >= 0 && gainLeft <= 20) { + return String.valueOf(gainLeft); + } else if (gainLeft >= 226 && gainLeft <= 255) { + return String.valueOf(gainLeft - 256); + } + break; + case "right": + if (gainRight >= 0 && gainRight <= 20) { + return String.valueOf(gainRight); + } else if (gainRight >= 226 && gainRight <= 255) { + return String.valueOf(gainRight - 256); + } } + return ""; } @@ -323,6 +391,44 @@ public static boolean hasHeadphoneGain() { return Utils.existFile(HEADPHONE_GAIN); } + public static void setHeadphoneGain(String channel, String value, Context context) { + int newGain = Utils.strToInt(value); + switch (channel) { + case "all": + if (newGain >= 0 && newGain <= 20) { + // Zero / 1 to 20 (positive gain range) + fauxRun(value + " " + value, HEADPHONE_GAIN, HEADPHONE_GAIN, context); + } else if (newGain <= -1 && newGain >= -30) { + // -1 to -30 (negative gain range) + value = String.valueOf(newGain + 256); + fauxRun(value + " " + value, HEADPHONE_GAIN, HEADPHONE_GAIN, context); + } + break; + case "left": + String currentGainRight = getHeadphoneGain("right"); + if (newGain >= 0 && newGain <= 20) { + // Zero / 1 to 20 (positive gain range) + fauxRun(value + " " + currentGainRight, HEADPHONE_GAIN, HEADPHONE_GAIN, context); + } else if (newGain <= -1 && newGain >= -30) { + // -1 to -30 (negative gain range) + value = String.valueOf(newGain + 256); + fauxRun(value + " " + currentGainRight, HEADPHONE_GAIN, HEADPHONE_GAIN, context); + } + break; + case "right": + String currentGainLeft = getHeadphoneGain("left"); + if (newGain >= 0 && newGain <= 20) { + // Zero / 1 to 20 (positive gain range) + fauxRun(currentGainLeft + " " + value, HEADPHONE_GAIN, HEADPHONE_GAIN, context); + } else if (newGain <= -1 && newGain >= -30) { + // -1 to -30 (negative gain range) + value = String.valueOf(newGain + 256); + fauxRun(currentGainLeft + " " + value, HEADPHONE_GAIN, HEADPHONE_GAIN, context); + } + break; + } + } + public static void enableHighPerfMode(boolean enable, Context context) { run(Control.write(enable ? "1" : "0", HIGHPERF_MODE_ENABLE), HIGHPERF_MODE_ENABLE, context); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c60d58bf5..a6ee1bda0 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -525,6 +525,11 @@ Prevent modifications to microphone gains Microphone Gain Volume Gain + Per-channel controls + Use different gain values for each channel + All Channels + Left Channel + Right Channel Level