Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for more products #105

Merged
merged 29 commits into from
May 3, 2021
Merged

Add support for more products #105

merged 29 commits into from
May 3, 2021

Conversation

mrene
Copy link
Owner

@mrene mrene commented Apr 24, 2021

Starting to gather the requirements for multiple devices.

Aiming to support:

Todos:

  • Create codegen stubs for new devices
  • Adjust probe to detect new devices by hw id
  • Make the dev tools / logging use the symbol map of each device
  • Add CLI and minidspd options to force a device type
  • Expand USB probing to include minidsp's old vendor and device id
  • Map 4x10HD peripherals (this doesn't look too much like a 2x4HD, so I'll need some external help)
  • Map SHD peripherals
  • Map MiniSHARC peripherals

@professorpolymath
Copy link

Hello, if I can assist with either the 4x10HD (2x8) or the OpenDRC (4x8) please let me know what you need.

@mrene
Copy link
Owner Author

mrene commented Apr 24, 2021

Thank you! I'm going to finish tweaking the verbose output so that it gives you human-readable addresses. Then it should be a matter of opening the plugin app and taking notes about what does what.

@mrene
Copy link
Owner Author

mrene commented Apr 25, 2021

@professorpolymath question regarding the minisharc:

  • is there feedback from the compressor levels using the plugin app? on the 2x4hd I have meter addresses to read the current compressor level. There doesn't seem to be any for the minisharc.
  • that device can work in both 48000hz and 96000hz - which is the plugin version of the files you sent me?

@professorpolymath
Copy link

I used the 96kHz version of miniSHARC 4x8 plugin. The plugin gives visual feedback of compression level when active.
minisharc_comp

@mrene
Copy link
Owner Author

mrene commented Apr 29, 2021

Thanks. I must not have recognized the name of that value.

The last commit pushes what's needed in order to gather information about the devices. I've extracted all the addresses (from the xml config) through some custom code generating a list of symbols. Most of the configuration is handled through these and go through the same command with a changing address. Reading values from the device also uses that same address space, but since devices don't allow reading back the config, they all read zeros unless they report some audio levels (like input/output gain and compressor feedback).

There is some logic in how these symbols are used for, what I'm looking for first is confirmation that I have done the right mapping for the miniSHARC (because the symbols were very similar to the 2x4HD). The only part I'm really missing is the compressor feedback, which should you should see flying by the console when viewing the UI you've shown me in the screenshot.

For the 4x10 I think we'll need to change each param and take note of what does what. Since there is some logic involved I'd start by doing it for one input and one output channel, so we can see the pattern and then confirm it's the same for the rest of the channels.

Gathering info

Grab the latest build from this branch (at the bottom of this page).

Confirm that probe is finding the right device - I baked in the ids that you provided me so that should work. This is important because it'll display the address mapping corresponding to this device.

$ minidsp probe
Found 2x4HD with serial 965535 at usb:0001%3A0005%3A04?vid=2752&pid=0011 [hw_id: 10, dsp_version: 100]

Start the server component with verbosity on (-v will display all commands except for ReadFloats, -vv will also include ReadFloats which you'll need to check in order to see the volume level feedback for channels and compressors (but it's so noisy otherwise that I usually keep it off), -vvv will include a full hex dump, which shouldn't be necessary).

Connect to the server component with the official plugin app, you'll see a bunch of things:

root@tvpi:/home/pi# ./minidsp-0.1 -v server

# All of this happens when the app first probes for the device kind
Sent: ReadHardwareId
Recv: HardwareId { payload: [01, 0a, 0a] }
Sent: ReadMemory { addr: ffa1, size: 01 }
Recv: MemoryData(MemoryView { base: ffa1, data: [64] })
Sent: ReadMemory { addr: fffc, size: 02 }
Recv: MemoryData(MemoryView { base: fffc, data: [ff, ff] })

# Plugin app connects here
# These ReadMemory aren't so important for this mapping

Sent: ReadMemory { addr: ffa1, size: 01 }
Recv: MemoryData(MemoryView { base: ffa1, data: [64] })
Sent: ReadHardwareId
Recv: HardwareId { payload: [01, 0a, 0a] }
Sent: ReadMemory { addr: ffc8, size: 10 }
Recv: MemoryData(MemoryView { base: ffc8, data: [03, 64, 00, a1, 02, b6, e3, 24, 00, 5b, b9, 5a, 00, e6, a3, 6d] })
Sent: ReadMemory { addr: ffd9, size: 01 }
Recv: MemoryData(MemoryView { base: ffd9, data: [01] })
Sent: ReadMemory { addr: ffd8, size: 01 }
Recv: MemoryData(MemoryView { base: ffd8, data: [00] })
Sent: ReadMemory { addr: fffe, size: 02 }
Recv: MemoryData(MemoryView { base: fffe, data: [ff, ff] })
Sent: ReadMemory { addr: ffe5, size: 01 }
Recv: MemoryData(MemoryView { base: ffe5, data: [00] })
Sent: ReadMemory { addr: ffe0, size: 01 }
Recv: MemoryData(MemoryView { base: ffe0, data: [00] })
Sent: ReadMemory { addr: ffda, size: 02 }
Recv: MemoryData(MemoryView { base: ffda, data: [2c, 00] })

# Plugin loaded

# Change input 0 mute on
Sent: Write { addr: 00, value: Value { Int: 1 (Bytes: [1, 0, 0, 0]) } } (0x00 | 0) <> D_GAIN_1_0_STATUS
Recv: Ack

# This is the plugin changing the "last change timestamp" - we don't care about these
Sent: WriteMemory { addr: ffc8, data: [03, 21, 9a, 0d] }
Recv: Ack

# Change input 0 mute off
Sent: Write { addr: 00, value: Value { Int: 2 (Bytes: [2, 0, 0, 0]) } } (0x00 | 0) <> D_GAIN_1_0_STATUS
Recv: Ack

In that example, we can associate the mute of input channel 0 to D_GAIN_1_0_STATUS. Which maps to the configuration of the 2x4hd here:

pub const DEVICE: Device = Device {
product_name: "2x4HD",
sources: &[Analog, Toslink, Usb],
inputs: &[
Input {
gate: Gate {
enable: D_GAIN_1_0_STATUS,
gain: D_GAIN_1_0,
},
meter: METER_02_C1_0,

Here is the same file but for the minisharc:

#[allow(unused_imports)]
use sym::*;
pub const DEVICE: Device = Device {
product_name: "MiniSHARC 4x8",
sources: &[],
inputs: &[
Input {
gate: Gate {
enable: D_GAIN_1_0_STATUS,
gain: D_GAIN_1_0,
},
meter: METER_04_C1_0,

These are all generated, so we're looking for the logic so we can write something like this:

pub(crate) fn input(input: usize) -> Input {
Input {
gate: Gate {
enable: format!("DGain_{}_0_status", input + 1),
gain: format!("DGain_{}_0", input + 1),
},
meter: format!("Meter04_C1_{}", input),
peq: (0..10usize)
.map(|index| format!("PEQ_{}_{}", input + 1, 10 - index))
.collect(),

Well that was a bit of a long post, let me know what I missed that isn't obvious 😅

@professorpolymath
Copy link

what I'm looking for first is confirmation that I have done the right mapping for the miniSHARC (because the symbols were very similar to the 2x4HD). The only part I'm really missing is the compressor feedback, which should you should see flying by the console when viewing the UI you've shown me in the screenshot.

miniSharc plugin open to output tab.
First set of values (0xb0) appear to be the output volume meter levels.
Second set (0xa8) could be the compressor readings -- the second instance below is after I enabled comp on output1.

# ./minidsp -vv server
Sent: [14, 00, b0, 08]
Sent: ReadFloats { addr: b0, len: 08 } (0xb0 | 176) <> METER_10_C2_0
Recv: [14, 00, b0, 02, 3c, 1c, c3, 02, 3c, 1c, c3, 41, e5, 24, c3, 41, e5, 24, c3, 00, 00, f0, c2, 00, 00, f0, c2, e9, 51, 04, c3, e9, 51, 04, c3]
Recv: FloatData(FloatView { base: b0, data: [-156.2344, -156.2344, -164.89552, -164.89552, -120.0, -120.0, -132.31996, -132.31996] })
Sent: [14, 00, a8, 08]
Sent: ReadFloats { addr: a8, len: 08 } (0xa8 | 168) <> METER_10_C1_0
Recv: [14, 00, a8, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00]
Recv: FloatData(FloatView { base: a8, data: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] })

Sent: [14, 00, b0, 08]
Sent: ReadFloats { addr: b0, len: 08 } (0xb0 | 176) <> METER_10_C2_0
Recv: [14, 00, b0, dd, 1a, f8, c1, 74, 54, cc, c1, ea, 11, e3, c1, 74, 64, d6, c1, 00, 00, f0, c2, 00, 00, f0, c2, b5, 19, 07, c2, eb, 08, 02, c2]
Recv: FloatData(FloatView { base: b0, data: [-31.013117, -25.541237, -28.383747, -26.79905, -120.0, -120.0, -33.775105, -32.50871] })
Sent: [14, 00, a8, 08]
Sent: ReadFloats { addr: a8, len: 08 } (0xa8 | 168) <> METER_10_C1_0
Recv: [14, 00, a8, 82, 0f, f0, bf, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00]
Recv: FloatData(FloatView { base: a8, data: [-1.8754733, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] })

@professorpolymath
Copy link

Confirm that probe is finding the right device

 ./minidsp probe
Found MiniSHARC 4x8 with serial 900260 at usb:IOService%3A%2FAppleACPIPlatformExpert%2FPCI0%400%2FAppleACPIPCI%2FXHC1%4014%2FXHC1%4014000000%2FHS02%4014200000%2FminiSHARC%20v1.0b%4014200000%2FIOUSBHostInterface%400%2FAppleUserUSBHostHIDDevice?vid=04d8&pid=003f [hw_id: 4, dsp_version: 66]
./minidsp -v
Sent: ReadHardwareId
Recv: HardwareId { payload: [02, 17, 04] }
Sent: ReadMemory { addr: ffa1, size: 01 }
Recv: MemoryData(MemoryView { base: ffa1, data: [42] })
Sent: ReadMemory { addr: fffc, size: 02 }
Recv: MemoryData(MemoryView { base: fffc, data: [01, 04] })
Sent: ReadMemory { addr: ffd8, size: 08 }
Recv: MemoryData(MemoryView { base: ffd8, data: [00, 08, 00, 00, ff, ff, ff, ff] })
MasterStatus { preset: Some(0), source: Some(NotInstalled), volume: Some(Gain(-0.0)), mute: Some(false) }
Input levels: -120.0, -120.0, -131.5, -131.5
Output levels: -163.0, -163.0, -167.2, -167.2, -120.0, -120.0, -132.8, -132.8

miniSharc -- while plugin running, muting the four inputs in turn

./minidsp -v server

#MUTE i2s input1
Sent: Write { addr: 00, value: Value { Int: 1 (Bytes: [1, 0, 0, 0]) } } (0x00 | 0) <> D_GAIN_1_0_STATUS
#UNMUTE
Sent: Write { addr: 00, value: Value { Int: 2 (Bytes: [2, 0, 0, 0]) } } (0x00 | 0) <> D_GAIN_1_0_STATUS

#MUTE i2s input2
Sent: Write { addr: 01, value: Value { Int: 1 (Bytes: [1, 0, 0, 0]) } } (0x01 | 1) <> D_GAIN_2_0_STATUS
#UNMUTE
Sent: Write { addr: 01, value: Value { Int: 2 (Bytes: [2, 0, 0, 0]) } } (0x01 | 1) <> D_GAIN_2_0_STATUS

#MUTE spdif input1
Sent: Write { addr: 02, value: Value { Int: 1 (Bytes: [1, 0, 0, 0]) } } (0x02 | 2) <> D_GAIN_3_0_STATUS
#UNMUTE
Sent: Write { addr: 02, value: Value { Int: 2 (Bytes: [2, 0, 0, 0]) } } (0x02 | 2) <> D_GAIN_3_0_STATUS

#MUTE spdif input2
Sent: Write { addr: 03, value: Value { Int: 1 (Bytes: [1, 0, 0, 0]) } } (0x03 | 3) <> D_GAIN_4_0_STATUS
#UNMUTE
Sent: Write { addr: 03, value: Value { Int: 2 (Bytes: [2, 0, 0, 0]) } } (0x03 | 3) <> D_GAIN_4_0_STATUS

@mrene
Copy link
Owner Author

mrene commented May 2, 2021

Second set (0xa8) could be the compressor readings -- the second instance below is after I enabled comp on output1.

Ah great. I've adjusted the device spec for the msharc4x8.
Mapping the OpenDRC is gonna be the more tedious part now, hopefully the commands are simiar enough.

@mrene mrene marked this pull request as ready for review May 3, 2021 01:47
@mrene mrene merged commit 9c1cbea into dev May 3, 2021
@mrene mrene deleted the msharc4x8 branch May 3, 2021 03:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants