fix broken git repository

master
Nicolò Balzarotti 2019-12-21 11:56:31 +01:00
parent b6ae04383d
commit 377ceccb30
3 changed files with 239 additions and 0 deletions

View File

@ -22,5 +22,6 @@ public final class HereConstants {
public static final UUID UUID_VOLUME = UUID.fromString(String.format(BASE_HERE_UUID, "e7"));
// TODO: Put device in sleep mode, (byte)0x00 sleep, (byte)0x01 wake
public static final UUID UUID_SLEEP = UUID.fromString(String.format(BASE_HERE_UUID, "eb"));
public static final UUID UUID_EQ = UUID.fromString(String.format(BASE_HERE_UUID, "e3"));
public static final UUID UUID_EFFECTS = UUID.fromString(String.format(BASE_HERE_UUID, "e9"));
}

View File

@ -0,0 +1,194 @@
package nodomain.freeyourgadget.gadgetbridge.entities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.LoggingExceptionHandler;
/**
* Created by Nicolò Balzarotti on 10/10/17.
*/
public class AudioEffect implements Serializable {
private static final Logger LOG = LoggerFactory.getLogger(LoggingExceptionHandler.class);
// Hopefully does not impact too much on performances. Params are usually less than 6
private List<Object> params = new ArrayList<Object>();
private AudioEffectType type;
boolean enable;
public AudioEffect(AudioEffectType type, int volume) {
if (type == AudioEffectType.VOLUME) {
LOG.debug("Create volume control effect");
this.type = type;
this.params.add(volume);
this.enable = true;
} else {
LOG.error("This constructor (effect, int) works only for volume!");
LOG.debug("Effect passed: " + type.name());
}
}
public AudioEffect(AudioEffectType type, boolean enable, List<Object> params) {
this.type = type;
this.enable = enable;
this.params = params;
}
public AudioEffect(AudioEffectType type, boolean enable) {
AudioEffect e = new AudioEffect(type, enable, getDefaultParams(type));
this.type = e.type;
this.enable = e.enable;
this.params = e.params;
}
public void addParameter(Object o) {
this.params.add(o);
}
;
public AudioEffectType getType() {
return this.type;
}
public byte[] toByteMessage() {
List<Byte> message = new ArrayList<>();
if (enable) {
if (type != AudioEffectType.VOLUME) {
message.add((byte) (type.getId() + 0x80));
}
} else if (type != AudioEffectType.VOLUME) {
// Disable just by sending the effect id
message.add((byte) type.getId());
return byteListToArray(message);
}
LOG.debug("Converting parameters");
for (Object param : params) {
if (param instanceof String && ((String) param).equals("3byte")) {
for (int i = 0; i < 3; ++i) {
message.add((byte) 0x00);
}
} else if (param instanceof Float) {
for (byte b : intToBytes(little2big((float) param))) {
message.add(b);
}
} else if (param instanceof Double) {
for (byte b : intToBytes24(float32toQ24((float) ((double) param)))) {
message.add(b);
}
} else if (param instanceof Integer && type == AudioEffectType.VOLUME) {
LOG.debug("The volume int value is " + param);
message.add((byte) ((int) param));
} else {
LOG.error("Programming error, unknown parameter");
}
}
return byteListToArray(message);
}
private static List<Object> getDefaultParams(AudioEffectType type) {
LOG.debug("Getting default parameters for effect of type " + type.name());
List<Object> params = new ArrayList<Object>();
switch (type) {
case ECHO:
params.add("3byte");
params.add(0.3f); // delay time
params.add(0.4f); // level
break;
case REVERB:
params.add("3byte");
params.add(1.8f);
params.add(1.2f);
params.add(0.015f);
break;
case CHORUS:
params.add(0.5); // Q24 rate
params.add(0.02f); // depth
params.add(0.02f); // delay
params.add(0.7f); // wet
params.add(0.7f); // dry
break;
case NOISEMASK:
params.add("3byte");
params.add(0.1f); // wet
params.add(0.0f); // dry
params.add(0.0f); // seed (random int)
break;
case FUZZ:
params.add("3byte");
params.add(0.05f); // cutoff
params.add(0.02f); // wet
params.add(0.02f); // dry
params.add(60.0f); // ramp factor
break;
case FLANGE:
params.add(0.3625); // rate (double converted to FixedP24)
params.add(0.009f); // depth
params.add(0.0f); // delay
params.add(-0.7f); // wet (left)
// params.add(0.7f); // wet (right) // we'll set it differently when we'll manage
// L/R separately
params.add(1.0f); // dry
break;
case BASSBOOST:
params.add("3byte");
params.add(-10.0f); // treble gain
params.add(10.0f); // global gain
break;
case BITCRUSHER:
params.add("3byte");
params.add(65536.0f); // bit num
params.add(12000.0f); // bit freq
break;
default:
LOG.warn("Programming error! Enabled a non-existent effect ("
+ type.name() + "!");
}
return params;
}
// ADD ONLY THE FIRST 3 byte! (24bit!)
private static byte[] intToBytes24(int i) {
return new byte[]{
(byte) ((i >>> 0) & 0xff),
(byte) ((i >>> 8) & 0xff), // 8 and 16 might be inverted
(byte) ((i >>> 16) & 0xff)
};
}
private static byte[] intToBytes(int i) {
return new byte[]{
(byte) (i >>> 24),
(byte) (i >>> 16),
(byte) (i >>> 8),
(byte) i
};
}
private static int little2big(float f) {
return Integer.reverseBytes(Float.floatToRawIntBits(f));
}
private static int float32toQ24(float f) {
int i = (int) (f * 16777216); // 2^24
LOG.debug(Integer.toHexString(i));
i = (i >> 8) | (i << 16);
return i;
}
private byte[] byteListToArray(List<Byte> message) {
byte[] byteMessage = new byte[message.size()];
for (int i = 0; i < message.size(); ++i) {
byteMessage[i] = message.get(i);
}
return byteMessage;
}
}

View File

@ -0,0 +1,44 @@
package nodomain.freeyourgadget.gadgetbridge.entities;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Nicolò Balzarotti on 10/9/17.
*/
public enum AudioEffectType {
// Volume
VOLUME(0, 0),
// Equalizer
EQ(10, 0),
// Effects
ECHO(20, 1), REVERB(21, 2), NOISEMASK(22, 3), FUZZ(23, 4),
// TAPE(24, 5), // disabled in real app too, probably not implemented
FLANGE(26, 7),
CHORUS(27, 8),
BITCRUSHER(28, 9),
BASSBOOST(29, 10);
private final int key;
private final int effect_id;
public int getKey() { return key; }
public int getId() { return effect_id; }
AudioEffectType(int key, int effect_id) {
this.key = key;
this.effect_id = effect_id;
}
public static AudioEffectType getByEffectId(int id) {
for (AudioEffectType e : AudioEffectType.values()) {
if (e.effect_id == id) {
return e;
}
}
return null;// not found
}
}