Skip to content

Commit

Permalink
eq progress
Browse files Browse the repository at this point in the history
  • Loading branch information
gmallios committed May 4, 2024
1 parent f6d0698 commit e08b132
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 29 deletions.
8 changes: 8 additions & 0 deletions manager-app/src/async_bridge/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,11 @@ pub struct SetSoundModePayload {
pub addr: BluetoothAdrr,
pub sound_mode: SoundMode,
}

#[derive(Debug, Deserialize, Clone)]
#[typeshare]
#[serde(rename_all = "camelCase")]
pub enum SetEqualizerPayload {
SetCustomEqualizer,
SetEqualizerPreset,
}
26 changes: 17 additions & 9 deletions manager-ui/src/components/EqualizerCard/equalizer.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { ChartData } from 'chart.js';
import { useCallback, useState } from 'react';
import { Line } from 'react-chartjs-2';
import 'chartjs-plugin-dragdata';
import {
Chart as ChartJS,
CategoryScale,
Chart as ChartJS,
ChartData,
Filler,
Legend,
LinearScale,
PointElement,
LineElement,
PointElement,
Title,
Tooltip,
Legend,
Filler
Tooltip
} from 'chart.js';
import { useCallback, useState } from 'react';
import { Line } from 'react-chartjs-2';
import 'chartjs-plugin-dragdata';
import { Button } from '@mui/material';

ChartJS.register(
CategoryScale,
Expand Down Expand Up @@ -66,6 +67,12 @@ export const Equalizer = ({ bands, input, onEqualizerChange }: EqualizerProps):
console.log('Equalizer output:', newDataSet);
};

const onResetClick = () => {
const newDataSet = Array(bands).fill(0);
setDataSet(newDataSet);
onEqualizerChange(newDataSet);
};

//@ts-expect-error: no type found for this event
const onHover = useCallback((e) => {
const point = e?.chart.getElementsAtEventForMode(e, 'nearest', { intersect: true }, false);
Expand Down Expand Up @@ -111,6 +118,7 @@ export const Equalizer = ({ bands, input, onEqualizerChange }: EqualizerProps):
return (
<>
<Line data={data} options={options} />
<Button onClick={() => onResetClick()}>Reset</Button>
</>
);
};
42 changes: 30 additions & 12 deletions manager-ui/src/components/EqualizerCard/equalizerCard.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { Paper } from '@mui/material';
import { Collapse, MenuItem, Paper, Select, SelectChangeEvent, Stack } from '@mui/material';
import { Equalizer } from './equalizer';
import { SoundcoreDeviceState } from '@generated-types/soundcore-lib';
import { EQProfile, SoundcoreDeviceState } from '@generated-types/soundcore-lib';
import { useCallback } from 'react';

export interface EqualizerCardProps {
state: SoundcoreDeviceState;
}

export const EqualizerCard = ({ state }: EqualizerCardProps): JSX.Element => {
const onEqualizerChange = useCallback((output: number[]) => {
const onCustomEqualizerChange = useCallback((output: number[]) => {
console.log('Equalizer output:', output);
console.log('Equalizer output mapped:', mapRangeArray(output, -6, 6, 0, 240));
}, []);

const onSelectedEqProfileChange = (e: SelectChangeEvent) => {
console.log('Selected EQ profile:', e.target.value);
};

const mapRange = (
value: number,
inMin: number,
Expand Down Expand Up @@ -40,21 +44,35 @@ export const EqualizerCard = ({ state }: EqualizerCardProps): JSX.Element => {
} else {
valueArr = state.eqConfiguration.value.eq.values;
}
console.log('EQ values:', valueArr);
return mapRangeArray(valueArr, 0, 240, -6, 6);
};

console.log('Mapped EQ values:', getMappedEqValues());
const eqProfiles = Object.keys(EQProfile).filter((item) => {
return isNaN(Number(item));
});

const isOnCustom = state.eqConfiguration.value.profile === EQProfile.Custom;

return (
<Paper sx={{ display: 'flex', margin: 3, justifyContent: 'center', alignItems: 'center' }}>
{state.featureSet.equalizerFeatures && (
<Equalizer
bands={state.featureSet.equalizerFeatures.bands}
input={[...getMappedEqValues()]}
onEqualizerChange={onEqualizerChange}
/>
)}
<Stack sx={{ width: '100%' }}>
<Select value={state.eqConfiguration.value.profile} onChange={onSelectedEqProfileChange}>
{eqProfiles.map((profile) => (
<MenuItem key={profile} value={profile}>
{profile}
</MenuItem>
))}
</Select>
{state.featureSet.equalizerFeatures && (
<Collapse in={isOnCustom} timeout="auto">
<Equalizer
bands={state.featureSet.equalizerFeatures.bands}
input={[...getMappedEqValues()]}
onEqualizerChange={onCustomEqualizerChange}
/>
</Collapse>
)}
</Stack>
</Paper>
);
};
5 changes: 5 additions & 0 deletions manager-ui/src/types/tauri-backend.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ export type BridgeCommand =
| { command: 'disconnectAll'; payload?: undefined }
| { command: 'setSoundMode'; payload: SetSoundModePayload };

export enum SetEqualizerPayload {
SetCustomEqualizer = 'setCustomEqualizer',
SetEqualizerPreset = 'setEqualizerPreset'
}

export type BridgeResponse =
| { kind: 'scanResult'; payload: DiscoveredDevice[] }
| { kind: 'connectionEstablished'; payload: TaggedStateResponse }
Expand Down
4 changes: 3 additions & 1 deletion soundcore-lib/src/devices/a3040/eq_update_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ impl Packet for A3040EqUpdateCommand {
fn command(&self) -> [u8; 7] {
match self.bass_up.0 {
true => [0x08, 0xEE, 0x00, 0x00, 0x00, 0x02, 0x84],
false => todo!(),
false => [0x08, 0xEE, 0x00, 0x00, 0x00, 0x03, 0x87],
}
}

fn payload(&self) -> Vec<u8> {
// 2 bytes profile - FEFE - Custom
//
todo!()
}
}
33 changes: 33 additions & 0 deletions soundcore-lib/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use env_logger::{Builder, Target};
use log::LevelFilter;

use soundcore_lib::ble::{BLEConnectionFactory, BLEConnectionManager};
use soundcore_lib::device_manager::create_device_manager;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
Builder::new()
.target(Target::Stdout)
.filter_level(LevelFilter::Trace)
.init();
let manager = create_device_manager().await;
let scan_res = manager.ble_scan(None).await?;
println!("{:?}", scan_res);
let device = scan_res
.iter()
.find(|d| d.descriptor.name.contains("Q45"))
.unwrap();
let connection = manager.connect(device.clone()).await?;

let mut state_channel = connection.state_channel().await;

while let Ok(()) = state_channel.changed().await {
println!("{:?}", state_channel.borrow_and_update());
}
// let registry = BtlePlugDeviceRegistry::new().await?;
// let scan_res = registry.scan(None).await?;
// println!("{:?}", scan_res);
// let q45 = scan_res.iter().find(|d| d.name.contains("Q45")).unwrap();
// let _connection = registry.connect(q45.clone(), None).await?;
Ok(())
}
2 changes: 1 addition & 1 deletion soundcore-lib/src/parsers/packet_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ fn parse_packet_kind<'a, E: ParseError<'a>>(bytes: &'a [u8]) -> ParseResult<Resp
context(
"parse_packet_header",
map_opt(take(2usize), |bytes: &[u8]| {
trace!("Parsing packet kind: {:?}", bytes);
trace!("Parsing packet kind: {:X?}", bytes);
PACKET_KIND_MAP
.iter()
.find(|(map_bytes, _)| map_bytes == &bytes)
Expand Down
52 changes: 52 additions & 0 deletions soundcore-lib/tests/a3040.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use soundcore_lib::{packets::ResponsePacket, types::SupportedModels};

Check failure on line 1 in soundcore-lib/tests/a3040.rs

View workflow job for this annotation

GitHub Actions / Run tests with stable Rust

unresolved import `soundcore_lib::types::SupportedModels`

#[test]
fn should_parse_state_update() {
let packet = ResponsePacket::from_bytes(&test_data::a3040::UNKN);
match packet {
Ok(ResponsePacket::DeviceState(state)) => {
// TODO: Assert state
assert_eq!(state.tag, SupportedModels::A3040);
println!("{:?}", state.data);
}
Err(err) => panic!("Failed to parse state update packet, error: {:X?}", err),
_ => panic!("Parsed as wrong packet type"),
}
}

#[test]
fn should_parse_sound_mode_update_packet() {
// Normal
// {
// let packet = ResponsePacket::from_bytes(&test_data::a3040::SOUND_MODE_UPDATE_NORMAL);
// match packet {
// Ok(ResponsePacket::SoundModeUpdate(state)) => {
// assert_eq!(state.0.current, CurrentSoundMode::Normal);
// }
// Err(_err) => panic!("Failed to parse state update packet"),
// _ => panic!("Parsed as wrong packet type"),
// }
// }
// // Noise Cancelling
// {
// let packet = ResponsePacket::from_bytes(&test_data::a3040::SOUND_MODE_UPDATE_NOISE_CANCELLING);
// match packet {
// Ok(ResponsePacket::SoundModeUpdate(state)) => {
// todo!()
// }
// Err(_err) => panic!("Failed to parse state update packet"),
// _ => panic!("Parsed as wrong packet type"),
// }
// }
// // Transparency
// {
// let packet = ResponsePacket::from_bytes(&test_data::a3040::SOUND_MODE_UPDATE_TRANSPARENCY);
// match packet {
// Ok(ResponsePacket::SoundModeUpdate(state)) => {
// todo!()
// }
// Err(_err) => panic!("Failed to parse state update packet"),
// _ => panic!("Parsed as wrong packet type"),
// }
// }
}
31 changes: 26 additions & 5 deletions test_data/src/a3040.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ pub const A3040_STATE_UPDATE_BYTES: [u8; 152] = [
0x78, 0x78, 0x78, 0x78, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x57,
];

pub const UNKN: [u8; 152] = [
0x9, 0xFF, 0x0, 0x0, 0x1, 0x1, 0x1, 0x98, 0x0, 0x5, 0xFF, 0x30, 0x36, 0x2E, 0x33, 0x34, 0x33,
0x30, 0x34, 0x30, 0x45, 0x41, 0x43, 0x33, 0x35, 0x36, 0x43, 0x43, 0x45, 0x45, 0x45, 0x38, 0x2,
0x0, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x0, 0x0, 0x78, 0x78, 0x78, 0x78, 0x78,
0x78, 0x78, 0x78, 0x0, 0x0, 0x4, 0x4, 0x7, 0x7, 0x1, 0x51, 0x1, 0x0, 0x0, 0x3, 0xFF, 0x0, 0x0,
0xFF, 0x1, 0x31, 0x0, 0x1, 0xFF, 0x0, 0x1, 0x1, 0x0, 0x5A, 0x0, 0x1, 0x1, 0x0, 0x2, 0x0, 0x32,
0xFF, 0x0, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x0, 0x0, 0x3C, 0x3C, 0x3C, 0x3C,
0x3C, 0x3C, 0x3C, 0x3C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3C, 0x3C, 0x3C, 0x3C, 0xB4, 0x3C,
0xB4, 0x3C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x78, 0x78, 0x78, 0x78,
0x78, 0x78, 0x78, 0x78, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5C,
];

pub const anc: [u8; 152] = [

Check warning on line 25 in test_data/src/a3040.rs

View workflow job for this annotation

GitHub Actions / Run cargo check

constant `anc` should have an upper case name
0x9, 0xFF, 0x0, 0x0, 0x1, 0x1, 0x1, 0x98, 0x0, 0x2, 0xFF, 0x30, 0x36, 0x2E, 0x33, 0x34, 0x33,
0x30, 0x34, 0x30, 0x45, 0x41, 0x43, 0x33, 0x35, 0x36, 0x43, 0x43, 0x45, 0x45, 0x45, 0x38, 0x0,
Expand Down Expand Up @@ -59,8 +71,17 @@ pub const max_eq: [u8; 152] = [
0x7C, 0x7C, 0x7C, 0x7E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77,
];

pub const SOUND_MODE_UPDATE_NOISE_CANCELLING: [u8; 16] = [0x9, 0xFF, 0x0, 0x0, 0x1, 0x6, 0x1, 0x10, 0x0, 0x0, 0x51, 0x1, 0x1, 0x0, 0x5, 0x78];
pub const SOUND_MODE_UPDATE_TRANSPARENCY: [u8; 16] = [0x9, 0xFF, 0x0, 0x0, 0x1, 0x6, 0x1, 0x10, 0x0, 0x1, 0x50, 0x1, 0x1, 0x0, 0x5, 0x78];
pub const SOUND_MODE_UPDATE_NORMAL: [u8; 16] = [0x9, 0xFF, 0x0, 0x0, 0x1, 0x6, 0x1, 0x10, 0x0, 0x2, 0x50, 0x1, 0x1, 0x0, 0x5, 0x79];
pub const BASS_UP_UPDATE_ENABLE: [u8; 12] = [0x9, 0xFF, 0x0, 0x0, 0x1, 0x2, 0x1, 0xC, 0x0, 0x2, 0x0, 0x1A];
pub const BASS_UP_UPDATE_DISABLE: [u8; 12] = [0x9, 0xFF, 0x0, 0x0, 0x1, 0x2, 0x1, 0xC, 0x0, 0xFE, 0xFE, 0x14];
pub const SOUND_MODE_UPDATE_NOISE_CANCELLING: [u8; 16] = [
0x9, 0xFF, 0x0, 0x0, 0x1, 0x6, 0x1, 0x10, 0x0, 0x0, 0x51, 0x1, 0x1, 0x0, 0x5, 0x78,
];
pub const SOUND_MODE_UPDATE_TRANSPARENCY: [u8; 16] = [
0x9, 0xFF, 0x0, 0x0, 0x1, 0x6, 0x1, 0x10, 0x0, 0x1, 0x50, 0x1, 0x1, 0x0, 0x5, 0x78,
];
pub const SOUND_MODE_UPDATE_NORMAL: [u8; 16] = [
0x9, 0xFF, 0x0, 0x0, 0x1, 0x6, 0x1, 0x10, 0x0, 0x2, 0x50, 0x1, 0x1, 0x0, 0x5, 0x79,
];
pub const BASS_UP_UPDATE_ENABLE: [u8; 12] =
[0x9, 0xFF, 0x0, 0x0, 0x1, 0x2, 0x1, 0xC, 0x0, 0x2, 0x0, 0x1A];
pub const BASS_UP_UPDATE_DISABLE: [u8; 12] = [
0x9, 0xFF, 0x0, 0x0, 0x1, 0x2, 0x1, 0xC, 0x0, 0xFE, 0xFE, 0x14,
];
2 changes: 1 addition & 1 deletion test_data/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pub mod a3040;
pub mod a3951;
pub mod a3040;

0 comments on commit e08b132

Please sign in to comment.