ot-tools-io 0.11.3

A library crate for reading/writing binary data files used by the Elektron Octatrack DPS-1.
Documentation
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2026 Mike Robeson [dijksterhuis]
*/

//! Current settings for the Project Mixer

use crate::projects::parse_hashmap_string_value;
use crate::projects::ProjectParseError;
use ot_tools_io_derive::{AsMutDerive, AsRefDerive};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// Global `MIXER` UI menu.
#[derive(
    Copy,
    Clone,
    Debug,
    Eq,
    Hash,
    Ord,
    PartialEq,
    PartialOrd,
    Serialize,
    Deserialize,
    AsMutDerive,
    AsRefDerive,
)]
pub struct MixerMenu {
    /// Controls the incoming gain of external audio signal through AB inputs. -64 to +63 range.
    /// See Manual section 8.8 MIXER MENU
    pub gain_ab: u8,

    /// Controls the incoming gain of external audio signal through CD inputs. -64 to +63 range.
    /// See Manual section 8.8 MIXER MENU
    pub gain_cd: u8,

    /// Routes audio from AB inputs directly to mixer outputs. 0 to 127 range.
    /// See Manual section 8.8 MIXER MENU
    pub dir_ab: u8,

    /// Routes audio from CD inputs directly to mixer outputs. 0 to 127 range.
    /// See Manual section 8.8 MIXER MENU
    pub dir_cd: u8,

    /// How much to mix the master / cue outputs on the headphones output. 0 to 127 range with 64 the default (equal mix)
    /// See Manual section 8.8 MIXER MENU
    pub phones_mix: u8,

    /// Mix between Main and Cue for headphones out.
    /// See Manual section 8.8 MIXER MENU
    pub main_to_cue: u8,

    /// Final gain / output level of the main outputs. -64 to 63 range. 0 is default.
    /// See Manual section 8.8 MIXER MENU
    pub main_level: u8,

    /// Final gain / output level of the cue outputs. -64 to 63 range. 0 is default.
    /// See Manual section 8.8 MIXER MENU
    pub cue_level: u8,
}

impl Default for MixerMenu {
    fn default() -> Self {
        Self {
            gain_ab: 64,
            gain_cd: 64,
            dir_ab: 0,
            dir_cd: 0,
            phones_mix: 64,
            main_to_cue: 0,
            main_level: 64,
            cue_level: 64,
        }
    }
}

impl TryFrom<&HashMap<String, String>> for MixerMenu {
    type Error = ProjectParseError;
    fn try_from(value: &HashMap<String, String>) -> Result<Self, Self::Error> {
        let gain_ab = parse_hashmap_string_value::<u8>(value, "gain_ab", None)?;
        let gain_cd = parse_hashmap_string_value::<u8>(value, "gain_cd", None)?;
        let dir_ab = parse_hashmap_string_value::<u8>(value, "dir_ab", None)?;
        let dir_cd = parse_hashmap_string_value::<u8>(value, "dir_cd", None)?;
        let phones_mix = parse_hashmap_string_value::<u8>(value, "phones_mix", None)?;
        let main_to_cue = parse_hashmap_string_value::<u8>(value, "main_to_cue", None)?;
        let main_level = parse_hashmap_string_value::<u8>(value, "main_level", None)?;
        let cue_level = parse_hashmap_string_value::<u8>(value, "cue_level", None)?;
        Ok(Self {
            gain_ab,
            gain_cd,
            dir_ab,
            dir_cd,
            phones_mix,
            main_to_cue,
            main_level,
            cue_level,
        })
    }
}