From 6bdc4bbcab695411b98fb6ffcca9d6abc6c70dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Balzarotti?= Date: Mon, 9 Oct 2017 23:36:35 +0200 Subject: [PATCH] Lot of work on HERE support. Almost working effects + GUI EQ --- app/src/main/AndroidManifest.xml | 2 +- .../activities/AudioActivity.java | 67 --- .../activities/AudioSettingsActivity.java | 134 ++++++ .../adapter/GBDeviceAdapterv2.java | 5 +- .../gadgetbridge/devices/EventHandler.java | 3 +- .../devices/here/HereConstants.java | 1 + .../devices/here/HereCoordinator.java | 5 +- .../gadgetbridge/impl/GBDeviceService.java | 6 +- .../gadgetbridge/model/DeviceService.java | 4 + .../service/DeviceCommunicationService.java | 9 +- .../service/ServiceDeviceSupport.java | 5 +- .../service/devices/here/HereSupport.java | 382 +++++++----------- .../service/devices/hplus/HPlusSupport.java | 3 +- .../devices/jyou/TeclastH30Support.java | 3 +- .../devices/liveview/LiveviewSupport.java | 3 +- .../service/devices/miband/MiBandSupport.java | 3 +- .../devices/miband2/MiBand2Support.java | 3 +- .../service/devices/no1f1/No1F1Support.java | 3 +- .../service/devices/pebble/PebbleSupport.java | 3 +- .../vibratissimo/VibratissimoSupport.java | 2 +- .../res/layout/activity_audio_settings.xml | 220 ++++++++++ app/src/main/res/layout/audio_settings.xml | 16 - app/src/main/res/values-it/strings.xml | 3 + app/src/main/res/values/strings.xml | 14 + 24 files changed, 552 insertions(+), 347 deletions(-) delete mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AudioActivity.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AudioSettingsActivity.java create mode 100644 app/src/main/res/layout/activity_audio_settings.xml delete mode 100644 app/src/main/res/layout/audio_settings.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4c43d314..9a40fb60 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -389,7 +389,7 @@ android:label="@string/title_activity_vibration" android:parentActivityName=".activities.ControlCenterv2" /> . */ - -package nodomain.freeyourgadget.gadgetbridge.activities; - -import android.os.Bundle; -import android.widget.SeekBar; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.UUID; - -import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.R; -import nodomain.freeyourgadget.gadgetbridge.devices.here.HereConstants; -import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; -import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; - - -public class AudioActivity extends AbstractGBActivity { - private static final Logger LOG = LoggerFactory.getLogger(AudioActivity.class); - private SeekBar seekBar; - private int volume; - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.audio_settings); - LOG.info("Create"); - - seekBar = (SeekBar) findViewById(R.id.volume_seekbar); - seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int position, boolean fromUser) { - // HERE's volume range is from 0xe3 (-22dB on their app) to 0xff (+6dB) - // 0xff - 0xe3 = 28 -> seekbar max value - // volume = seekbar + Min_volume (= 0xe3 = 227) - volume = position + 227; - LOG.debug("Volume = " + (byte)volume + " = " + volume + "= " + position); - GBApplication.deviceService().onSetAudioProperty(0, volume); - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - } - }); - } -} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AudioSettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AudioSettingsActivity.java new file mode 100644 index 00000000..6f3ba137 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AudioSettingsActivity.java @@ -0,0 +1,134 @@ +/* Copyright (C) 2016-2017 Andreas Shimokawa, Carsten Pfeiffer + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ + +package nodomain.freeyourgadget.gadgetbridge.activities; + +import android.os.Bundle; +import android.view.View; +import android.widget.CheckedTextView; +import android.widget.SeekBar; +import android.widget.TextView; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; + +public class AudioSettingsActivity extends AbstractGBActivity { + private static final Logger LOG = LoggerFactory.getLogger(AudioSettingsActivity.class); + private SeekBar seekBar; + private TextView volume_text; + private CheckedTextView cbBassBoost; + private CheckedTextView cbNoiseMask; + + // private boolean[] enabledEffects; + + private int volume; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_audio_settings); + LOG.debug("Create Audio Setttings interface"); + + // All of this is because HERE can't handle more than 2 effects. + // You _can_ enable them, but the device will not be able to manage them in realtime + // and you'll get "Xruns". We prevent more than 2 simultaneous checks (like their app does) + // But it's commented out until I'll read the one already enabled. Else this is useless :D + /*enabledEffects = new boolean[] { + false // echo + , false // reverb + , false // noise mask + , false // fuzz + , false // flange + , false // bass boost + };*/ + + seekBar = (SeekBar) findViewById(R.id.volume_seekbar); + volume_text = (TextView) findViewById(R.id.volume_seekbar_volume); + + seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int position, boolean fromUser) { + // HERE's volume range is from 0xe3 (-22dB on their app) to 0xff (+6dB) + // 0xff - 0xe3 = 28 -> seekbar max value + // volume = seekbar + Min_volume (= 0xe3 = 227) + volume = position + 227; + // LOG.debug("Volume = " + (byte)volume + " = " + volume + "= " + position); + GBApplication.deviceService().onSetAudioProperty(AudioEffectType.VOLUME.getKey(), + new float[] {volume}); + // Show the volume on the UI in dB (range -22;6) + volume_text.setText(" " + (position - 22) + " dB"); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + }); + + // FIXME: we need to read the current value and display this. + // right now, I'm just showing 0 dB, Called after changeListener sets the value on + // the device too. + seekBar.setProgress(22); + + cbBassBoost = (CheckedTextView) findViewById(R.id.audio_effect_bassboost); + + cbBassBoost.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + ((CheckedTextView) v).toggle(); + LOG.info("Enabled bassBoost"); + applyEffect(AudioEffectType.BASSBOOST, ((CheckedTextView) v).isChecked()); + } + }); + + cbNoiseMask = (CheckedTextView) findViewById(R.id.audio_effect_noisemask); + + cbNoiseMask.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + ((CheckedTextView) v).toggle(); + LOG.info("Enabled noisemask"); + applyEffect(AudioEffectType.NOISEMASK, ((CheckedTextView) v).isChecked()); + } + }); + + cbNoiseMask = (CheckedTextView) findViewById(R.id.audio_effect_echo); + + cbNoiseMask.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + ((CheckedTextView) v).toggle(); + LOG.info("Enabled echo"); + applyEffect(AudioEffectType.ECHO, ((CheckedTextView) v).isChecked()); + } + }); + } + + void applyEffect(AudioEffectType effect, boolean enable) { + GBApplication.deviceService().onSetAudioProperty( + effect.getId(), + new float[] { + enable ? 1.0f : 0.0f, + // FIXME: add other params? + }); + + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java index 26dafe35..c3bbcd15 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java @@ -42,12 +42,11 @@ import android.widget.Toast; import java.util.List; import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.GBEnvironment; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms; import nodomain.freeyourgadget.gadgetbridge.activities.VibrationActivity; import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity; -import nodomain.freeyourgadget.gadgetbridge.activities.AudioActivity; +import nodomain.freeyourgadget.gadgetbridge.activities.AudioSettingsActivity; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; @@ -221,7 +220,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter getPrimaryActivity() { - return AudioActivity.class; + return AudioSettingsActivity.class; } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java index 7229b215..20ad9a42 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -33,6 +33,7 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; @@ -305,10 +306,11 @@ public class GBDeviceService implements DeviceService { } @Override - public void onSetAudioProperty(int property, int intensity) { + public void onSetAudioProperty(int property, float[] params) { // volume = 0 Intent intent = createIntent().setAction(ACTION_SET_AUDIO_PROPERTY) - .putExtra(EXTRA_AUDIO_PROPERTY, intensity); + .putExtra(EXTRA_AUDIO_PROPERTY, property) + .putExtra(EXTRA_AUDIO_PARAMS, params); invokeService(intent); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java index 19524e3f..87e87c50 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java @@ -20,6 +20,7 @@ package nodomain.freeyourgadget.gadgetbridge.model; import android.support.annotation.Nullable; import nodomain.freeyourgadget.gadgetbridge.devices.EventHandler; +import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; @@ -78,6 +79,7 @@ public interface DeviceService extends EventHandler { String EXTRA_FIND_START = "find_start"; String EXTRA_VIBRATION_INTENSITY = "vibration_intensity"; String EXTRA_AUDIO_PROPERTY = "audio_property"; + String EXTRA_AUDIO_PARAMS = "audio_params"; String EXTRA_CALL_COMMAND = "call_command"; String EXTRA_CALL_PHONENUMBER = "call_phonenumber"; String EXTRA_CALL_DISPLAYNAME = "call_displayname"; @@ -154,4 +156,6 @@ public interface DeviceService extends EventHandler { * from the service will be reported. */ void requestDeviceInfo(); + + void onSetAudioProperty(int property, float[] params); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 4c0750b3..752a00ae 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -105,6 +105,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_ST import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_STARTAPP; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_TEST_NEW_FUNCTION; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_ALARMS; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_AUDIO_PARAMS; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_AUDIO_PROPERTY; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP_CONFIG; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP_START; @@ -431,8 +432,12 @@ public class DeviceCommunicationService extends Service implements SharedPrefere } case ACTION_SET_AUDIO_PROPERTY: { LOG.info(mDeviceSupport.getDevice().toString()); - int volume = intent.getIntExtra(EXTRA_AUDIO_PROPERTY, 0); - mDeviceSupport.onSetAudioProperty(0, volume); + int property = intent.getIntExtra(EXTRA_AUDIO_PROPERTY, 999); + float [] params = intent.getFloatArrayExtra(EXTRA_AUDIO_PARAMS); + LOG.debug(" "+property); + LOG.debug(""+params[0]); + mDeviceSupport.onSetAudioProperty(property, params); + LOG.debug("Called"); break; } case ACTION_CALLSTATE: diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java index 281c71cd..e0b20abb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java @@ -28,6 +28,7 @@ import java.util.ArrayList; import java.util.EnumSet; import java.util.UUID; +import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; @@ -153,8 +154,8 @@ public class ServiceDeviceSupport implements DeviceSupport { } @Override - public void onSetAudioProperty(int property, int intensity) { - delegate.onSetAudioProperty(property, intensity); + public void onSetAudioProperty(int property, float [] params) { + delegate.onSetAudioProperty(property, params); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/here/HereSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/here/HereSupport.java index bccc466b..ff88ca7e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/here/HereSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/here/HereSupport.java @@ -18,25 +18,19 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.here; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; - -import static nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport.BASE_UUID; - import android.net.Uri; -import android.widget.Toast; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; import java.util.ArrayList; -import java.util.Calendar; +import java.util.Arrays; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; import nodomain.freeyourgadget.gadgetbridge.devices.here.HereConstants; +import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; @@ -48,8 +42,6 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; -import nodomain.freeyourgadget.gadgetbridge.util.GB; -import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; public class HereSupport extends AbstractBTLEDeviceSupport { @@ -59,7 +51,7 @@ public class HereSupport extends AbstractBTLEDeviceSupport { public BluetoothGattCharacteristic infoCharacteristic = null; public BluetoothGattCharacteristic fwCharacteristic = null; public BluetoothGattCharacteristic volumeCharacteristic = null; - + public BluetoothGattCharacteristic effectCharacteristic = null; private final GBDeviceEventVersionInfo versionCmd = new GBDeviceEventVersionInfo(); private final GBDeviceEventBatteryInfo batteryCmd = new GBDeviceEventBatteryInfo(); @@ -67,7 +59,7 @@ public class HereSupport extends AbstractBTLEDeviceSupport { super(LOG); addSupportedService(HereConstants.UUID_BATTERY_VALUE); addSupportedService(HereConstants.UUID_CHARACTERISTIC_INFO); - addSupportedService(HereConstants.UUID_AUDIO_SETTINGS); + addSupportedService(HereConstants.UUID_AUDIO_SETTINGS); } @Override @@ -80,14 +72,15 @@ public class HereSupport extends AbstractBTLEDeviceSupport { batteryCharacteristic = getCharacteristic(HereConstants.UUID_CHARACTERISTIC_BATTERY); infoCharacteristic = getCharacteristic(HereConstants.UUID_CHARACTERISTIC_INFO); fwCharacteristic = getCharacteristic(HereConstants.UUID_CHARACTERISTIC_INFO); - volumeCharacteristic = getCharacteristic(HereConstants.UUID_VOLUME); + volumeCharacteristic = getCharacteristic(HereConstants.UUID_VOLUME); + effectCharacteristic = getCharacteristic(HereConstants.UUID_EFFECTS); builder.setGattCallback(this); builder.notify(batteryCharacteristic, true); builder.read(fwCharacteristic); syncSettings(builder); - // fw = builder.read(infoCharacteristic); + // fw = builder.read(infoCharacteristic); gbDevice.setState(GBDevice.State.INITIALIZED); gbDevice.sendDeviceUpdateIntent(getContext()); @@ -114,112 +107,24 @@ public class HereSupport extends AbstractBTLEDeviceSupport { handleGBDeviceEvent(batteryCmd); return true; } else if (HereConstants.UUID_FW_VERSION.equals(characteristicUUID)) { - LOG.info("Device info: " + (short)data[0]); + LOG.info("Device info: " + (short) data[0]); LOG.info("Device info: " + data); versionCmd.fwVersion = String.format("%s", data); handleGBDeviceEvent(versionCmd); - } else { + return true; + } else { return true; } - return true; } - private void syncDateAndTime(TransactionBuilder builder) { - // Calendar cal = Calendar.getInstance(); - // String strYear = String.valueOf(cal.get(Calendar.YEAR)); - // byte year1 = (byte)Integer.parseInt(strYear.substring(0, 2)); - // byte year2 = (byte)Integer.parseInt(strYear.substring(2, 4)); - // byte month = (byte)cal.get(Calendar.MONTH); - // byte day = (byte)cal.get(Calendar.DAY_OF_MONTH); - // byte hour = (byte)cal.get(Calendar.HOUR_OF_DAY); - // byte minute = (byte)cal.get(Calendar.MINUTE); - // byte second = (byte)cal.get(Calendar.SECOND); - // byte weekDay = (byte)cal.get(Calendar.DAY_OF_WEEK); - // builder.write(ctrlCharacteristic, commandWithChecksum( - // HereConstants.CMD_SET_DATE_AND_TIME, - // (year1 << 24) | (year2 << 16) | (month << 8) | day, - // (hour << 24) | (minute << 16) | (second << 8) | weekDay - // )); + private void syncDateAndTime(TransactionBuilder builder) { } private void syncSettings(TransactionBuilder builder) { - // syncDateAndTime(builder); - - // // TODO: unhardcode and separate stuff - // builder.write(ctrlCharacteristic, commandWithChecksum( - // HereConstants.CMD_SET_HEARTRATE_WARNING_VALUE, 0, 152 - // )); - // builder.write(ctrlCharacteristic, commandWithChecksum( - // HereConstants.CMD_SET_TARGET_STEPS, 0, 10000 - // )); - // builder.write(ctrlCharacteristic, commandWithChecksum( - // HereConstants.CMD_GET_STEP_COUNT, 0, 0 - // )); - // builder.write(ctrlCharacteristic, commandWithChecksum( - // HereConstants.CMD_GET_SLEEP_TIME, 0, 0 - // )); - // builder.write(ctrlCharacteristic, commandWithChecksum( - // HereConstants.CMD_SET_NOON_TIME, 12 * 60 * 60, 14 * 60 * 60 // 12:00 - 14:00 - // )); - // builder.write(ctrlCharacteristic, commandWithChecksum( - // HereConstants.CMD_SET_SLEEP_TIME, 21 * 60 * 60, 8 * 60 * 60 // 21:00 - 08:00 - // )); - // builder.write(ctrlCharacteristic, commandWithChecksum( - // HereConstants.CMD_SET_INACTIVITY_WARNING_TIME, 0, 0 - // )); - - // // do not disturb and a couple more features - // byte dndStartHour = 22; - // byte dndStartMin = 0; - // byte dndEndHour = 8; - // byte dndEndMin = 0; - // boolean dndToggle = false; - // boolean vibrationToggle = true; - // boolean wakeOnRaiseToggle = true; - // builder.write(ctrlCharacteristic, commandWithChecksum( - // HereConstants.CMD_SET_DND_SETTINGS, - // (dndStartHour << 24) | (dndStartMin << 16) | (dndEndHour << 8) | dndEndMin, - // ((dndToggle ? 0 : 1) << 2) | ((vibrationToggle ? 1 : 0) << 1) | (wakeOnRaiseToggle ? 1 : 0) - // )); } private void showNotification(byte icon, String title, String message) { - // try { - // TransactionBuilder builder = performInitialized("ShowNotification"); - - // byte[] titleBytes = stringToUTF8Bytes(title, 16); - // byte[] messageBytes = stringToUTF8Bytes(message, 80); - - // for (int i = 1; i <= 7; i++) - // { - // byte[] currentPacket = new byte[20]; - // currentPacket[0] = HereConstants.CMD_ACTION_SHOW_NOTIFICATION; - // currentPacket[1] = 7; - // currentPacket[2] = (byte)i; - // switch(i) { - // case 1: - // currentPacket[4] = icon; - // break; - // case 2: - // if (titleBytes != null) { - // System.arraycopy(titleBytes, 0, currentPacket, 3, 6); - // System.arraycopy(titleBytes, 6, currentPacket, 10, 10); - // } - // break; - // default: - // if (messageBytes != null) { - // System.arraycopy(messageBytes, 16 * (i - 3), currentPacket, 3, 6); - // System.arraycopy(messageBytes, 6 + 16 * (i - 3), currentPacket, 10, 10); - // } - // break; - // } - // builder.write(ctrlCharacteristic, currentPacket); - // } - // performConnected(builder.getTransaction()); - // } catch (IOException e) { - // LOG.warn(e.getMessage()); - // } } @Override @@ -229,27 +134,6 @@ public class HereSupport extends AbstractBTLEDeviceSupport { @Override public void onNotification(NotificationSpec notificationSpec) { - // String notificationTitle = StringUtils.getFirstOf(notificationSpec.sender, notificationSpec.title); - // byte icon; - // switch (notificationSpec.type) { - // case GENERIC_SMS: - // icon = HereConstants.ICON_SMS; - // break; - // case FACEBOOK: - // case FACEBOOK_MESSENGER: - // icon = HereConstants.ICON_FACEBOOK; - // break; - // case TWITTER: - // icon = HereConstants.ICON_TWITTER; - // break; - // case WHATSAPP: - // icon = HereConstants.ICON_WHATSAPP; - // break; - // default: - // icon = HereConstants.ICON_LINE; - // break; - // } - // showNotification(icon, notificationTitle, notificationSpec.body); } @Override @@ -259,57 +143,14 @@ public class HereSupport extends AbstractBTLEDeviceSupport { @Override public void onSetAlarms(ArrayList alarms) { - // try { - // TransactionBuilder builder = performInitialized("SetAlarms"); - - // for (int i = 0; i < alarms.size(); i++) - // { - // byte cmd; - // switch (i) { - // case 0: - // cmd = HereConstants.CMD_SET_ALARM_1; - // break; - // case 1: - // cmd = HereConstants.CMD_SET_ALARM_2; - // break; - // case 2: - // cmd = HereConstants.CMD_SET_ALARM_3; - // break; - // default: - // return; - // } - // Calendar cal = alarms.get(i).getAlarmCal(); - // builder.write(ctrlCharacteristic, commandWithChecksum( - // cmd, - // alarms.get(i).isEnabled() ? cal.get(Calendar.HOUR_OF_DAY) : -1, - // alarms.get(i).isEnabled() ? cal.get(Calendar.MINUTE) : -1 - // )); - // } - // performConnected(builder.getTransaction()); - // GB.toast(getContext(), "Alarm settings applied - do note that the current device does not support day specification", Toast.LENGTH_LONG, GB.INFO); - // } catch(IOException e) { - // LOG.warn(e.getMessage()); - // } } @Override public void onSetTime() { - // try { - // TransactionBuilder builder = performInitialized("SetTime"); - // syncDateAndTime(builder); - // performConnected(builder.getTransaction()); - // } catch(IOException e) { - // LOG.warn(e.getMessage()); - // } } @Override public void onSetCallState(CallSpec callSpec) { - // switch (callSpec.command) { - // case CallSpec.CALL_INCOMING: - // showNotification(HereConstants.ICON_CALL, callSpec.name, callSpec.number); - // break; - // } } @Override @@ -318,22 +159,62 @@ public class HereSupport extends AbstractBTLEDeviceSupport { } @Override - public void onSetAudioProperty(int property, int volume) { - TransactionBuilder builder = new TransactionBuilder("volume"); - LOG.info("setting audio"); - switch (property) { - case 0: // volume - LOG.info("setting volume to "+volume); + public void onSetAudioProperty(int property, float[] params) { + AudioEffectType effect = AudioEffectType.getByEffectId(property); + TransactionBuilder builder = createTransactionBuilder("SetAudio"); + switch (effect) { + case VOLUME: // volume + LOG.info("Setting the audio volume"); + if (params.length != 1) { + LOG.error("Wrong number of params"); + break; + } + // Only one param, the volume (int) + int volume = (int) params[0]; builder.write(volumeCharacteristic, new byte[]{(byte) volume}); - builder.queue(getQueue()); + break; + case ECHO: + case REVERB: + case NOISEMASK: + case FUZZ: + case FLANGE: + case BASSBOOST: + /*if (params.length < 2) { + LOG.error("Wrong number of params"); + break; + }*/ + // Bt dump: 81 (00 00 00) (9a99993e) (cdcccc3e) + // We add as a first param a boolean (enable/disable) + boolean enable = params[0] == 1.0; // 1.0 is true, other false + // float[] audioparams = Arrays.copyOfRange(params,1,params.length-1); + // enable with 80 + effect_id, + // disable with effect_id + byte[] message; + if (!enable) { + LOG.info("Disabling the " + effect.name() + " effect"); + // To disable an effect, you just need to transmit its effect id + message = new byte[] {(byte) effect.getId()}; + } else { + LOG.info("Enabling the " + effect.name() + " effect"); + message = createMessage(effect); + } + builder.write(effectCharacteristic, message); + break; + case EQ: + LOG.info("Enabling the EQ effect"); + LOG.warn("Still not implemented"); + break; + default: + LOG.warn("Programming error! non-existent audio effect value"); break; } + + builder.queue(getQueue()); } @Override public void onSetMusicState(MusicStateSpec stateSpec) { - } @Override @@ -383,42 +264,14 @@ public class HereSupport extends AbstractBTLEDeviceSupport { @Override public void onReboot() { - // try { - // TransactionBuilder builder = performInitialized("Reboot"); - // builder.write(ctrlCharacteristic, commandWithChecksum( - // HereConstants.CMD_ACTION_REBOOT_DEVICE, 0, 0 - // )); - // performConnected(builder.getTransaction()); - // } catch(Exception e) { - // LOG.warn(e.getMessage()); - // } } @Override public void onHeartRateTest() { - // try { - // TransactionBuilder builder = performInitialized("HeartRateTest"); - // builder.write(ctrlCharacteristic, commandWithChecksum( - // HereConstants.CMD_ACTION_HEARTRATE_SWITCH, 0, 1 - // )); - // performConnected(builder.getTransaction()); - // } catch(Exception e) { - // LOG.warn(e.getMessage()); - // } } @Override public void onEnableRealtimeHeartRateMeasurement(boolean enable) { - // // TODO: test - // try { - // TransactionBuilder builder = performInitialized("RealTimeHeartMeasurement"); - // builder.write(ctrlCharacteristic, commandWithChecksum( - // HereConstants.CMD_SET_HEARTRATE_AUTO, 0, enable ? 1 : 0 - // )); - // performConnected(builder.getTransaction()); - // } catch(Exception e) { - // LOG.warn(e.getMessage()); - // } } @Override @@ -465,48 +318,93 @@ public class HereSupport extends AbstractBTLEDeviceSupport { } - // private byte[] commandWithChecksum(byte cmd, int argSlot1, int argSlot2) - // { - // // ByteBuffer buf = ByteBuffer.allocate(10); - // // buf.put(cmd); - // // buf.putInt(argSlot1); - // // buf.putInt(argSlot2); + // TODO: USE THIS + // private byte[] effectMessage(int id, int padding, float [] params) {}; - // // byte[] bytesToWrite = buf.array(); + private byte[] createMessage(AudioEffectType effect) { + byte [] message; + // TODO: replace this with FloatToReverseIEE754 + switch (effect) { + case ECHO: + message = new byte[]{ + (byte) (effect.getId() + 0x80), + (byte) 0x00, (byte) 0x00, (byte) 0x00, // padding + (byte) 0x9a, (byte) 0x99, (byte) 0x99, (byte) 0x3e, // 0.3 + (byte) 0xcd, (byte) 0xcc, (byte) 0xcc, (byte) 0x3e // 0.4 + }; + break; - // // byte checksum = 0; - // // for (byte b : bytesToWrite) { - // // checksum += b; - // // } + case REVERB: + message = new byte[]{ + (byte) (effect.getId() + 0x80), + (byte) 0x00, (byte) 0x00, (byte) 0x00, // padding + (byte) 0x66, (byte) 0x66, (byte) 0xe6, (byte) 0x3f, + (byte) 0x9a, (byte) 0x99, (byte) 0x99, (byte) 0x3f, + (byte) 0x8f, (byte) 0xc2, (byte) 0x75, (byte) 0x3c + }; + break; - // // bytesToWrite[9] = checksum; + case NOISEMASK: + message = new byte[]{ + (byte) (effect.getId() + 0x80), + (byte) 0x00, (byte) 0x00, (byte) 0x00, // padding + (byte) 0xcd, (byte) 0xcc, (byte) 0xcc, (byte) 0x3d, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x79, (byte) 0x59, (byte) 0x82, (byte) 0xd0 + }; + break; - // ByteBuffer buf = ByteBuffer.allocate(10); - // return buf; - // } + case FUZZ: + message = new byte[]{ + (byte) (effect.getId() + 0x80), + (byte) 0x00, (byte) 0x00, (byte) 0x00, // padding + (byte) 0xcd, (byte) 0xcc, (byte) 0x4c, (byte) 0x3d, + (byte) 0x0a, (byte) 0xd7, (byte) 0xa3, (byte) 0x3c, + (byte) 0x0a, (byte) 0xd7, (byte) 0xa3, (byte) 0x3c, + (byte) 0x00, (byte) 0x00, (byte) 0x70, (byte) 0x42 + }; + break; - private byte[] stringToUTF8Bytes(String src, int byteCount) { - // try { - // if (src == null) - // return null; + case FLANGE: + message = new byte[] { + (byte) (effect.getId() + 0x80), + (byte) 0xcc, (byte) 0x5c, (byte) 0x00, // 0.3625 (fixed point ?fract24) + (byte) 0xbc, (byte) 0x74, (byte) 0x13, (byte) 0x3c, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x33, (byte) 0x33, (byte) 0x33, (byte) 0x3f, + (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x3f + }; + break; - // for (int i = src.length(); i > 0; i--) { - // String sub = src.substring(0, i); - // byte[] subUTF8 = sub.getBytes("UTF-8"); + case BASSBOOST: + message = new byte[]{ + (byte) (effect.getId() + 0x80), + (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x20, (byte) 0xc1, + (byte) 0x00, (byte) 0x00, (byte) 0x20, (byte) 0x41 + }; + break; - // if (subUTF8.length == byteCount) { - // return subUTF8; - // } - - // if (subUTF8.length < byteCount) { - // byte[] largerSubUTF8 = new byte[byteCount]; - // System.arraycopy(subUTF8, 0, largerSubUTF8, 0, subUTF8.length); - // return largerSubUTF8; - // } - // } - // } catch (UnsupportedEncodingException e) { - // LOG.warn(e.getMessage()); - // } - return null; + default: + LOG.warn("Programming error! Enabled a non-existent effect (" + + effect.name() + + "!"); + message = new byte[]{}; + } + return message; } + + static byte[] FloatToReverseIEE754(float value) { + // Thanks to Maldivia on IRC #java + // and to https://stackoverflow.com/questions/2183240/java-integer-to-byte-array#2183279 + int i = Float.floatToRawIntBits(value); + i = (i << 9) | (i >>> 23) & 0x1ff; + return new byte [] { + (byte)(i >>> 24), + (byte)(i >>> 16), + (byte)(i >>> 8), + (byte) value + }; + } + } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java index 5340b76b..b29fbbc0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java @@ -49,6 +49,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusConstants; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusCoordinator; +import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; @@ -432,7 +433,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { } @Override - public void onSetAudioProperty(int property, int volume) { + public void onSetAudioProperty(int property, float[] params) { } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/TeclastH30Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/TeclastH30Support.java index 63fbb40f..67b44b00 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/TeclastH30Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/TeclastH30Support.java @@ -34,6 +34,7 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; import nodomain.freeyourgadget.gadgetbridge.devices.jyou.JYouConstants; +import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; @@ -317,7 +318,7 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport { } @Override - public void onSetAudioProperty(int property, int volume) { + public void onSetAudioProperty(int property, float[] params) { } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewSupport.java index 19d3739f..3b1425a8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewSupport.java @@ -21,6 +21,7 @@ import android.net.Uri; import java.util.ArrayList; import java.util.UUID; +import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; @@ -106,7 +107,7 @@ public class LiveviewSupport extends AbstractSerialDeviceSupport { } @Override - public void onSetAudioProperty(int property, int volume) { + public void onSetAudioProperty(int property, float[] params) { } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java index e5175df2..adb3a0e3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java @@ -52,6 +52,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandFWHelper; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandSampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService; import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile; +import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySample; @@ -453,7 +454,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { } @Override - public void onSetAudioProperty(int property, int volume) { + public void onSetAudioProperty(int property, float[] params) { } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java index 1a18c749..ff3e41c3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java @@ -63,6 +63,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService; import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile; +import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySample; @@ -664,7 +665,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { } @Override - public void onSetAudioProperty(int property, int volume) { + public void onSetAudioProperty(int property, float[] params) { } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java index 19f5db7a..072ae630 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java @@ -42,6 +42,7 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInf import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; import nodomain.freeyourgadget.gadgetbridge.devices.no1f1.No1F1Constants; import nodomain.freeyourgadget.gadgetbridge.devices.no1f1.No1F1SampleProvider; +import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.No1F1ActivitySample; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; @@ -356,7 +357,7 @@ public class No1F1Support extends AbstractBTLEDeviceSupport { } @Override - public void onSetAudioProperty(int property, int volume) { + public void onSetAudioProperty(int property, float[] params) { } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java index 0b18c608..e6c7d53a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java @@ -31,6 +31,7 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity; +import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; @@ -128,7 +129,7 @@ public class PebbleSupport extends AbstractSerialDeviceSupport { } @Override - public void onSetAudioProperty(int property, int volume) { + public void onSetAudioProperty(int property, float[] params) { } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vibratissimo/VibratissimoSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vibratissimo/VibratissimoSupport.java index c9b12f2b..f89fc31d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vibratissimo/VibratissimoSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vibratissimo/VibratissimoSupport.java @@ -186,7 +186,7 @@ public class VibratissimoSupport extends AbstractBTLEDeviceSupport { } @Override - public void onSetAudioProperty(int property, int volume) { + public void onSetAudioProperty(int property, float [] params) { } diff --git a/app/src/main/res/layout/activity_audio_settings.xml b/app/src/main/res/layout/activity_audio_settings.xml new file mode 100644 index 00000000..1590446b --- /dev/null +++ b/app/src/main/res/layout/activity_audio_settings.xml @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/audio_settings.xml b/app/src/main/res/layout/audio_settings.xml deleted file mode 100644 index 952574c0..00000000 --- a/app/src/main/res/layout/audio_settings.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 21c1ddf1..3a0ed82f 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -396,4 +396,7 @@ Tentativo di connessione con: %1$s Abilitare Bluetooth per l\'individuazione dei dispositivi. Non connettersi + Echo + Volume + Fuzz \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a46a4a49..7deef71d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -476,4 +476,18 @@ Mute Reply Audio Settings + Echo + Reverb + Noise mask + Flange + Volume + Fuzz + Bass boost + Equalizer (EQ) + + 180 Hz + 360 Hz + 1.1 kHz + 3.3 kHz + 6.8 kHz