All effects working!

master
Nicolò Balzarotti 2017-10-10 00:05:43 +02:00
parent 6bdc4bbcab
commit 6c313e2e9b
21 changed files with 438 additions and 505 deletions

View File

@ -26,54 +26,55 @@ import android.widget.TextView;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.here.HereConstants;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffect;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType;
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
public class AudioSettingsActivity extends AbstractGBActivity { public class AudioSettingsActivity extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(AudioSettingsActivity.class); private static final Logger LOG = LoggerFactory.getLogger(AudioSettingsActivity.class);
private SeekBar seekBar; private SeekBar seekBar;
private TextView volume_text; private TextView volume_text;
private CheckedTextView cbBassBoost;
private CheckedTextView cbNoiseMask;
// private boolean[] enabledEffects; // private boolean[] enabledEffects;
private int volume; private int volume;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_audio_settings); setContentView(R.layout.activity_audio_settings);
LOG.debug("Create Audio Setttings interface"); LOG.debug("Create Audio Settings 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
};*/
// FIXME: read enabled effects too
// FIXME: and EQ values XD
seekBar = (SeekBar) findViewById(R.id.volume_seekbar); seekBar = (SeekBar) findViewById(R.id.volume_seekbar);
volume_text = (TextView) findViewById(R.id.volume_seekbar_volume); volume_text = (TextView) findViewById(R.id.volume_seekbar_volume);
int startingVolume = 30; // FIXME: how do I read it?
seekBar.setProgress(startingVolume);
setdB(startingVolume);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override @Override
public void onProgressChanged(SeekBar seekBar, int position, boolean fromUser) { public void onProgressChanged(SeekBar seekBar, int position, boolean fromUser) {
// HERE's volume range is from 0xe3 (-22dB on their app) to 0xff (+6dB) // HERE's volume range is from 0xdb (-30dB on their app) to 0xff (+6dB)
// 0xff - 0xe3 = 28 -> seekbar max value // 0xff - 0xdb = 36 -> seekbar max value
// volume = seekbar + Min_volume (= 0xe3 = 227) // volume = seekbar + Min_volume (= 0xdb = 219)
volume = position + 227; volume = position + 219;
// LOG.debug("Volume = " + (byte)volume + " = " + volume + "= " + position); // LOG.debug("Volume = " + (byte)volume + " = " + volume + "= " + position);
GBApplication.deviceService().onSetAudioProperty(AudioEffectType.VOLUME.getKey(), AudioEffect eff = new AudioEffect(AudioEffectType.VOLUME, volume);
new float[] {volume}); GBApplication.deviceService().onSetAudioProperty(eff);
// Show the volume on the UI in dB (range -22;6) // Show the volume on the UI in dB (range -30;6)
volume_text.setText(" " + (position - 22) + " dB"); setdB(position);
} }
@Override @Override
@ -89,46 +90,35 @@ public class AudioSettingsActivity extends AbstractGBActivity {
// FIXME: we need to read the current value and display this. // 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 // right now, I'm just showing 0 dB, Called after changeListener sets the value on
// the device too. // the device too.
seekBar.setProgress(22);
cbBassBoost = (CheckedTextView) findViewById(R.id.audio_effect_bassboost); Map<Integer, AudioEffectType> checkboxesIds = new HashMap<Integer, AudioEffectType>();
checkboxesIds.put(R.id.audio_effect_echo, AudioEffectType.ECHO);
checkboxesIds.put(R.id.audio_effect_bassboost, AudioEffectType.BASSBOOST);
checkboxesIds.put(R.id.audio_effect_fuzz, AudioEffectType.FUZZ);
checkboxesIds.put(R.id.audio_effect_flange, AudioEffectType.FLANGE);
checkboxesIds.put(R.id.audio_effect_reverb, AudioEffectType.REVERB);
checkboxesIds.put(R.id.audio_effect_noisemask, AudioEffectType.NOISEMASK);
checkboxesIds.put(R.id.audio_effect_bitcrusher, AudioEffectType.BITCRUSHER);
checkboxesIds.put(R.id.audio_effect_chorus, AudioEffectType.CHORUS);
cbBassBoost.setOnClickListener(new View.OnClickListener() { for (int id : checkboxesIds.keySet()) {
final AudioEffectType effect = checkboxesIds.get(id);
((CheckedTextView) findViewById(id)).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
((CheckedTextView) v).toggle(); ((CheckedTextView) v).toggle();
LOG.info("Enabled bassBoost"); LOG.info("Toggled " + effect.name());
applyEffect(AudioEffectType.BASSBOOST, ((CheckedTextView) v).isChecked()); applyEffect(new AudioEffect(effect, ((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) { private void setdB(int volume) {
GBApplication.deviceService().onSetAudioProperty( volume_text.setText(" " + (volume - 30) + " dB");
effect.getId(), }
new float[] {
enable ? 1.0f : 0.0f,
// FIXME: add other params?
});
void applyEffect(AudioEffect effect) {
GBApplication.deviceService().onSetAudioProperty(effect);
} }
} }

View File

@ -5,17 +5,17 @@
Gadgetbridge is free software: you can redistribute it and/or modify Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published 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 by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful, Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details. GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.adapter; package nodomain.freeyourgadget.gadgetbridge.adapter;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
@ -214,8 +214,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter<GBDeviceAdapterv2.Vi
// audio settings // audio settings
holder.showAudioSettings.setVisibility(device.isInitialized() && coordinator.supportsAudioSettings() ? View.VISIBLE : View.GONE); holder.showAudioSettings.setVisibility(device.isInitialized() && coordinator.supportsAudioSettings() ? View.VISIBLE : View.GONE);
holder.showAudioSettings.setOnClickListener(new View.OnClickListener() holder.showAudioSettings.setOnClickListener(new View.OnClickListener() {
{
@Override @Override
public void onClick(View v) { public void onClick(View v) {
showTransientSnackbar(R.string.controlcenter_snackbar_requested_screenshot); showTransientSnackbar(R.string.controlcenter_snackbar_requested_screenshot);
@ -277,17 +276,17 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter<GBDeviceAdapterv2.Vi
super.onDismissed(snackbar, event); super.onDismissed(snackbar, event);
} }
}).show(); }).show();
// ProgressDialog.show( // ProgressDialog.show(
// context, // context,
// context.getString(R.string.control_center_find_lost_device), // context.getString(R.string.control_center_find_lost_device),
// context.getString(R.string.control_center_cancel_to_stop_vibration), // context.getString(R.string.control_center_cancel_to_stop_vibration),
// true, true, // true, true,
// new DialogInterface.OnCancelListener() { // new DialogInterface.OnCancelListener() {
// @Override // @Override
// public void onCancel(DialogInterface dialog) { // public void onCancel(DialogInterface dialog) {
// GBApplication.deviceService().onFindDevice(false); // GBApplication.deviceService().onFindDevice(false);
// } // }
// }); // });
} }
} }
@ -449,7 +448,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter<GBDeviceAdapterv2.Vi
View snackbarView = snackbar.getView(); View snackbarView = snackbar.getView();
// change snackbar text color // change snackbar text color
int snackbarTextId = android.support.design.R.id.snackbar_text; int snackbarTextId = android.support.design.R.id.snackbar_text;
TextView textView = (TextView) snackbarView.findViewById(snackbarTextId); TextView textView = (TextView) snackbarView.findViewById(snackbarTextId);
//textView.setTextColor(); //textView.setTextColor();

View File

@ -20,8 +20,10 @@ package nodomain.freeyourgadget.gadgetbridge.devices;
import android.net.Uri; import android.net.Uri;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffect;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
@ -80,7 +82,7 @@ public interface EventHandler {
void onSetConstantVibration(int integer); void onSetConstantVibration(int integer);
void onSetAudioProperty(int property, float[] params); void onSetAudioProperty(AudioEffect effect);
void onScreenshotReq(); void onScreenshotReq();

View File

@ -24,16 +24,14 @@ import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.provider.ContactsContract; import android.provider.ContactsContract;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
// FIXME: REMOVE
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.UUID; import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffect;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
@ -50,8 +48,6 @@ import static nodomain.freeyourgadget.gadgetbridge.util.JavaExtensions.coalesce;
public class GBDeviceService implements DeviceService { public class GBDeviceService implements DeviceService {
protected final Context mContext; protected final Context mContext;
// FIXME: REMOVE
private static final Logger LOG = LoggerFactory.getLogger(DeviceCommunicationService.class);
private final Class<? extends Service> mServiceClass; private final Class<? extends Service> mServiceClass;
private final String[] transliterationExtras = new String[]{ private final String[] transliterationExtras = new String[]{
@ -306,11 +302,10 @@ public class GBDeviceService implements DeviceService {
} }
@Override @Override
public void onSetAudioProperty(int property, float[] params) { public void onSetAudioProperty(AudioEffect effect) {
// volume = 0 // volume = 0
Intent intent = createIntent().setAction(ACTION_SET_AUDIO_PROPERTY) Intent intent = createIntent().setAction(ACTION_SET_AUDIO_PROPERTY)
.putExtra(EXTRA_AUDIO_PROPERTY, property) .putExtra(EXTRA_AUDIO_PROPERTY, (Serializable) effect);
.putExtra(EXTRA_AUDIO_PARAMS, params);
invokeService(intent); invokeService(intent);
} }

View File

@ -19,7 +19,10 @@ package nodomain.freeyourgadget.gadgetbridge.model;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.devices.EventHandler; import nodomain.freeyourgadget.gadgetbridge.devices.EventHandler;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffect;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
@ -157,5 +160,5 @@ public interface DeviceService extends EventHandler {
*/ */
void requestDeviceInfo(); void requestDeviceInfo();
void onSetAudioProperty(int property, float[] params); void onSetAudioProperty(AudioEffect effect);
} }

View File

@ -40,7 +40,7 @@ public enum DeviceType {
EXRIZUK8(42, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled), EXRIZUK8(42, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled),
NO1F1(50, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled), NO1F1(50, R.drawable.ic_device_hplus, R.drawable.ic_device_hplus_disabled),
TECLASTH30(60, R.drawable.ic_device_h30_h10, R.drawable.ic_device_h30_h10_disabled), TECLASTH30(60, R.drawable.ic_device_h30_h10, R.drawable.ic_device_h30_h10_disabled),
// Single device made of L + R (71, 71) // Single device made of L + R (71, 72)
// but each earbut can be controlled independently // but each earbut can be controlled independently
HERE(70, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled), HERE(70, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled),
// HERER(71, R.drawable.ic_device_here, R.drawable.ic_device_here_disabled), // HERER(71, R.drawable.ic_device_here, R.drawable.ic_device_here_disabled),

View File

@ -39,6 +39,7 @@ import android.widget.Toast;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random; import java.util.Random;
import java.util.UUID; import java.util.UUID;
@ -46,6 +47,7 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffect;
import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmClockReceiver; import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmClockReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmReceiver; import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.BluetoothConnectReceiver; import nodomain.freeyourgadget.gadgetbridge.externalevents.BluetoothConnectReceiver;
@ -105,7 +107,6 @@ 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_STARTAPP;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_TEST_NEW_FUNCTION; 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_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_AUDIO_PROPERTY;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP_CONFIG; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP_CONFIG;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP_START; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP_START;
@ -218,7 +219,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
if (action.equals(GBDevice.ACTION_DEVICE_CHANGED)) { if (action.equals(GBDevice.ACTION_DEVICE_CHANGED)) {
GBDevice device = intent.getParcelableExtra(GBDevice.EXTRA_DEVICE); GBDevice device = intent.getParcelableExtra(GBDevice.EXTRA_DEVICE);
if (mGBDevice != null && mGBDevice.equals(device)) { if (mGBDevice != null && mGBDevice.equals(device)) {
mGBDevice = device; mGBDevice = device; // if is already .equals, why set it?
boolean enableReceivers = mDeviceSupport != null && (mDeviceSupport.useAutoConnect() || mGBDevice.isInitialized()); boolean enableReceivers = mDeviceSupport != null && (mDeviceSupport.useAutoConnect() || mGBDevice.isInitialized());
setReceiversEnableState(enableReceivers, mGBDevice.isInitialized(), DeviceHelper.getInstance().getCoordinator(device)); setReceiversEnableState(enableReceivers, mGBDevice.isInitialized(), DeviceHelper.getInstance().getCoordinator(device));
GB.updateNotification(mGBDevice.getName() + " " + mGBDevice.getStateString(), mGBDevice.isInitialized(), context); GB.updateNotification(mGBDevice.getName() + " " + mGBDevice.getStateString(), mGBDevice.isInitialized(), context);
@ -431,13 +432,8 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
break; break;
} }
case ACTION_SET_AUDIO_PROPERTY: { case ACTION_SET_AUDIO_PROPERTY: {
LOG.info(mDeviceSupport.getDevice().toString()); AudioEffect effect = (AudioEffect) intent.getSerializableExtra(EXTRA_AUDIO_PROPERTY);
int property = intent.getIntExtra(EXTRA_AUDIO_PROPERTY, 999); mDeviceSupport.onSetAudioProperty(effect);
float [] params = intent.getFloatArrayExtra(EXTRA_AUDIO_PARAMS);
LOG.debug(" "+property);
LOG.debug(""+params[0]);
mDeviceSupport.onSetAudioProperty(property, params);
LOG.debug("Called");
break; break;
} }
case ACTION_CALLSTATE: case ACTION_CALLSTATE:

View File

@ -26,8 +26,10 @@ import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffect;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
@ -154,8 +156,8 @@ public class ServiceDeviceSupport implements DeviceSupport {
} }
@Override @Override
public void onSetAudioProperty(int property, float [] params) { public void onSetAudioProperty(AudioEffect effect) {
delegate.onSetAudioProperty(property, params); delegate.onSetAudioProperty(effect);
} }
@Override @Override

View File

@ -25,11 +25,13 @@ import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
import nodomain.freeyourgadget.gadgetbridge.devices.here.HereConstants; import nodomain.freeyourgadget.gadgetbridge.devices.here.HereConstants;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffect;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
@ -84,6 +86,7 @@ public class HereSupport extends AbstractBTLEDeviceSupport {
gbDevice.setState(GBDevice.State.INITIALIZED); gbDevice.setState(GBDevice.State.INITIALIZED);
gbDevice.sendDeviceUpdateIntent(getContext()); gbDevice.sendDeviceUpdateIntent(getContext());
requestCurrentVolume();
LOG.info("Initialization Done"); LOG.info("Initialization Done");
@ -159,57 +162,15 @@ public class HereSupport extends AbstractBTLEDeviceSupport {
} }
@Override @Override
public void onSetAudioProperty(int property, float[] params) { public void onSetAudioProperty(AudioEffect effect) {
AudioEffectType effect = AudioEffectType.getByEffectId(property);
TransactionBuilder builder = createTransactionBuilder("SetAudio"); TransactionBuilder builder = createTransactionBuilder("SetAudio");
BluetoothGattCharacteristic characteristic;
switch (effect) { if (effect.getType() == AudioEffectType.VOLUME) {
case VOLUME: // volume characteristic = volumeCharacteristic;
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});
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 { } else {
LOG.info("Enabling the " + effect.name() + " effect"); characteristic = effectCharacteristic;
message = createMessage(effect);
} }
builder.write(effectCharacteristic, message); builder.write(characteristic, effect.toByteMessage());
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()); builder.queue(getQueue());
} }
@ -224,7 +185,6 @@ public class HereSupport extends AbstractBTLEDeviceSupport {
@Override @Override
public void onEnableRealtimeSteps(boolean enable) { public void onEnableRealtimeSteps(boolean enable) {
onEnableRealtimeHeartRateMeasurement(enable);
} }
@Override @Override
@ -321,90 +281,17 @@ public class HereSupport extends AbstractBTLEDeviceSupport {
// TODO: USE THIS // TODO: USE THIS
// private byte[] effectMessage(int id, int padding, float [] params) {}; // private byte[] effectMessage(int id, int padding, float [] params) {};
public int requestCurrentVolume() {
TransactionBuilder builder = createTransactionBuilder("getAudio");
builder.read(volumeCharacteristic);
LOG.debug(builder.toString());
return 1;
}
private byte[] createMessage(AudioEffectType effect) { private byte[] createMessage(AudioEffectType effect) {
byte [] message; byte [] message;
// TODO: replace this with FloatToReverseIEE754 AudioEffect eff = new AudioEffect(effect, true); // default params!
switch (effect) { message = eff.toByteMessage();
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;
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;
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;
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;
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;
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;
default:
LOG.warn("Programming error! Enabled a non-existent effect (" +
effect.name()
+ "!");
message = new byte[]{};
}
return message; 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
};
}
} }

View File

@ -49,6 +49,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusConstants; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusCoordinator;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffect;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
@ -433,7 +434,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
} }
@Override @Override
public void onSetAudioProperty(int property, float[] params) { public void onSetAudioProperty(AudioEffect effect) {
} }

View File

@ -34,6 +34,7 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
import nodomain.freeyourgadget.gadgetbridge.devices.jyou.JYouConstants; import nodomain.freeyourgadget.gadgetbridge.devices.jyou.JYouConstants;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffect;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
@ -318,7 +319,7 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport {
} }
@Override @Override
public void onSetAudioProperty(int property, float[] params) { public void onSetAudioProperty(AudioEffect effect) {
} }

View File

@ -21,7 +21,7 @@ import android.net.Uri;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.UUID; import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffect;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
@ -107,7 +107,7 @@ public class LiveviewSupport extends AbstractSerialDeviceSupport {
} }
@Override @Override
public void onSetAudioProperty(int property, float[] params) { public void onSetAudioProperty(AudioEffect effect) {
} }
@Override @Override

View File

@ -52,6 +52,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandFWHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandSampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile; import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffect;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.entities.Device;
@ -454,7 +455,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
} }
@Override @Override
public void onSetAudioProperty(int property, float[] params) { public void onSetAudioProperty(AudioEffect effect) {
} }

View File

@ -63,6 +63,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile; import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffect;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.entities.Device;
@ -665,7 +666,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
} }
@Override @Override
public void onSetAudioProperty(int property, float[] params) { public void onSetAudioProperty(AudioEffect effect) {
} }

View File

@ -42,6 +42,7 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInf
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
import nodomain.freeyourgadget.gadgetbridge.devices.no1f1.No1F1Constants; import nodomain.freeyourgadget.gadgetbridge.devices.no1f1.No1F1Constants;
import nodomain.freeyourgadget.gadgetbridge.devices.no1f1.No1F1SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.no1f1.No1F1SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffect;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType;
import nodomain.freeyourgadget.gadgetbridge.entities.No1F1ActivitySample; import nodomain.freeyourgadget.gadgetbridge.entities.No1F1ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
@ -357,7 +358,7 @@ public class No1F1Support extends AbstractBTLEDeviceSupport {
} }
@Override @Override
public void onSetAudioProperty(int property, float[] params) { public void onSetAudioProperty(AudioEffect effect) {
} }

View File

@ -26,11 +26,13 @@ import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity; import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffect;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType; import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
@ -129,7 +131,7 @@ public class PebbleSupport extends AbstractSerialDeviceSupport {
} }
@Override @Override
public void onSetAudioProperty(int property, float[] params) { public void onSetAudioProperty(AudioEffect effect) {
} }

View File

@ -29,10 +29,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffect;
import nodomain.freeyourgadget.gadgetbridge.entities.AudioEffectType;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
@ -186,7 +189,7 @@ public class VibratissimoSupport extends AbstractBTLEDeviceSupport {
} }
@Override @Override
public void onSetAudioProperty(int property, float [] params) { public void onSetAudioProperty(AudioEffect effect) {
} }

View File

@ -3,16 +3,16 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_centerHorizontal="false" android:layout_centerHorizontal="false"
android:orientation="vertical"
android:layout_centerInParent="false" android:layout_centerInParent="false"
android:layout_centerVertical="false" android:layout_centerVertical="false"
android:orientation="vertical"
android:weightSum="1"> android:weightSum="1">
<SeekBar <SeekBar
android:id="@+id/volume_seekbar" android:id="@+id/volume_seekbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:max="28" android:max="36"
android:scaleY="4.0" /> android:scaleY="4.0" />
<LinearLayout <LinearLayout
@ -21,20 +21,28 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:baselineAligned="false" android:baselineAligned="false"
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <TextView
android:id="@+id/volume_seekbar_text" android:id="@+id/volume_seekbar_text"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/audio_volume"/> android:text="@string/audio_volume" />
<TextView <TextView
android:id="@+id/volume_seekbar_volume" android:id="@+id/volume_seekbar_volume"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content" />
/>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/audio_effect_selector" android:id="@+id/audio_effect_selector_big"
android:layout_width="387dp"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:orientation="vertical">
<LinearLayout
android:id="@+id/audio_effect_selector_l1"
android:layout_width="387dp" android:layout_width="387dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:baselineAligned="false" android:baselineAligned="false"
@ -83,6 +91,14 @@
android:gravity="center" android:gravity="center"
android:text="@string/audio_effect_fuzz" android:text="@string/audio_effect_fuzz"
android:textAppearance="?android:attr/textAppearanceSmall" /> android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
<LinearLayout
android:id="@+id/audio_effect_selector"
android:layout_width="387dp"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:orientation="horizontal">
<android.support.v7.widget.AppCompatCheckedTextView <android.support.v7.widget.AppCompatCheckedTextView
android:id="@+id/audio_effect_flange" android:id="@+id/audio_effect_flange"
@ -95,6 +111,17 @@
android:text="@string/audio_effect_flange" android:text="@string/audio_effect_flange"
android:textAppearance="?android:attr/textAppearanceSmall" /> android:textAppearance="?android:attr/textAppearanceSmall" />
<android.support.v7.widget.AppCompatCheckedTextView
android:id="@+id/audio_effect_bitcrusher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_weight="1"
android:drawableTop="?android:attr/listChoiceIndicatorMultiple"
android:gravity="center"
android:text="@string/audio_effect_bitcrusher"
android:textAppearance="?android:attr/textAppearanceSmall" />
<android.support.v7.widget.AppCompatCheckedTextView <android.support.v7.widget.AppCompatCheckedTextView
android:id="@+id/audio_effect_bassboost" android:id="@+id/audio_effect_bassboost"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -106,16 +133,27 @@
android:text="@string/audio_effect_bassboost" android:text="@string/audio_effect_bassboost"
android:textAppearance="?android:attr/textAppearanceSmall" /> android:textAppearance="?android:attr/textAppearanceSmall" />
<android.support.v7.widget.AppCompatCheckedTextView
android:id="@+id/audio_effect_chorus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_weight="1"
android:drawableTop="?android:attr/listChoiceIndicatorMultiple"
android:gravity="center"
android:text="@string/audio_effect_chorus"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</LinearLayout> </LinearLayout>
<TextView <TextView
android:id="@+id/audio_equalizer_text" android:id="@+id/audio_equalizer_text"
android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:text="@string/audio_equalizer" android:text="@string/audio_equalizer" />
/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -123,98 +161,107 @@
android:baselineAligned="false" android:baselineAligned="false"
android:orientation="horizontal" android:orientation="horizontal"
android:weightSum="1"> android:weightSum="1">
<SeekBar <SeekBar
android:id="@+id/equalizer_band_0" android:id="@+id/equalizer_band_0"
android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:max="30" android:max="30"
android:scaleY="2.0" android:scaleY="2.0" />
android:layout_weight="1.0" />
<TextView <TextView
android:id="@+id/equalizer_band_0_text" android:id="@+id/equalizer_band_0_text"
android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:text="@string/equalizer_band_0" android:layout_height="wrap_content"
/> android:text="@string/equalizer_band_0" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:baselineAligned="false" android:baselineAligned="false"
android:orientation="horizontal" android:orientation="horizontal"
android:weightSum="1"> android:weightSum="1">
<SeekBar <SeekBar
android:id="@+id/equalizer_band_1" android:id="@+id/equalizer_band_1"
android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:max="30" android:max="30"
android:scaleY="2.0" android:scaleY="2.0" />
android:layout_weight="1.0" />
<TextView <TextView
android:id="@+id/equalizer_band_1_text" android:id="@+id/equalizer_band_1_text"
android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:text="@string/equalizer_band_1" android:layout_height="wrap_content"
/> android:text="@string/equalizer_band_1" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:baselineAligned="false" android:baselineAligned="false"
android:orientation="horizontal" android:orientation="horizontal"
android:weightSum="1"> android:weightSum="1">
<SeekBar <SeekBar
android:id="@+id/equalizer_band_2" android:id="@+id/equalizer_band_2"
android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:max="30" android:max="30"
android:scaleY="2.0" android:scaleY="2.0" />
android:layout_weight="1.0" />
<TextView <TextView
android:id="@+id/equalizer_band_2_text" android:id="@+id/equalizer_band_2_text"
android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:text="@string/equalizer_band_2" android:layout_height="wrap_content"
/> android:text="@string/equalizer_band_2" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:baselineAligned="false" android:baselineAligned="false"
android:orientation="horizontal" android:orientation="horizontal"
android:weightSum="1"> android:weightSum="1">
<SeekBar <SeekBar
android:id="@+id/equalizer_band_3" android:id="@+id/equalizer_band_3"
android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:max="30" android:max="30"
android:scaleY="2.0" android:scaleY="2.0" />
android:layout_weight="1.0" />
<TextView <TextView
android:id="@+id/equalizer_band_3_text" android:id="@+id/equalizer_band_3_text"
android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:text="@string/equalizer_band_3" android:layout_height="wrap_content"
/> android:text="@string/equalizer_band_3" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:baselineAligned="false" android:baselineAligned="false"
android:orientation="horizontal" android:orientation="horizontal"
android:weightSum="1"> android:weightSum="1">
<SeekBar <SeekBar
android:id="@+id/equalizer_band_4" android:id="@+id/equalizer_band_4"
android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:max="30" android:max="30"
android:scaleY="2.0" android:scaleY="2.0" />
android:layout_weight="1.0" />
<TextView <TextView
android:id="@+id/equalizer_band_4_text" android:id="@+id/equalizer_band_4_text"
android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:text="@string/equalizer_band_4" android:layout_height="wrap_content"
/> android:text="@string/equalizer_band_4" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -490,4 +490,6 @@
<string name="equalizer_band_2">1.1 kHz</string> <string name="equalizer_band_2">1.1 kHz</string>
<string name="equalizer_band_3">3.3 kHz</string> <string name="equalizer_band_3">3.3 kHz</string>
<string name="equalizer_band_4">6.8 kHz</string> <string name="equalizer_band_4">6.8 kHz</string>
<string name="audio_effect_bitcrusher">Bit Crusher</string>
<string name="audio_effect_chorus">Chorus</string>
</resources> </resources>