More work on sources

This commit is contained in:
Davide Passoni
2024-09-03 20:19:11 +02:00
parent b352bc824c
commit a64ccab15f
22 changed files with 604 additions and 281 deletions

View File

@@ -6,6 +6,7 @@ export function OlRangeSlider(props: {
max?: number;
step?: number;
className?: string;
vertical?: boolean;
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
}) {
var elementRef = useRef(null);
@@ -33,6 +34,7 @@ export function OlRangeSlider(props: {
h-2 w-full cursor-pointer appearance-none rounded-lg bg-gray-200
dark:bg-gray-700
`}
/>
);
}

View File

@@ -0,0 +1,49 @@
import React, { useEffect, useState } from "react";
import { OlStateButton } from "../../components/olstatebutton";
import { faPlay, faRepeat } from "@fortawesome/free-solid-svg-icons";
import { getApp } from "../../../olympusapp";
import { AudioSource } from "../../../audio/audiosource";
import { FaVolumeHigh } from "react-icons/fa6";
import { OlRangeSlider } from "../../components/olrangeslider";
export function AudioSourcePanel(props: { index: number; source: AudioSource }) {
return (
<div
className={`
flex flex-col content-center justify-between gap-2 rounded-md
bg-olympus-200/30 py-3 pl-4 pr-5
`}
>
Source: {props.source.getName()}
<div className="flex gap-4 py-2">
<OlStateButton
checked={false}
icon={faPlay}
onClick={() => {
let sources = getApp().getAudioManager().getSources();
sources[props.index].play();
}}
tooltip="Play file"
></OlStateButton>
<OlRangeSlider
value={50}
onChange={(ev) => {
//let setting = props.setting;
//setting.volume = parseFloat(ev.currentTarget.value) / 100;
//props.updateSetting(setting);
}}
className="my-auto"
/>
<OlStateButton
checked={false}
icon={faRepeat}
onClick={() => {
}}
tooltip="Loop"
></OlStateButton>
</div>
</div>
);
}

View File

@@ -0,0 +1,70 @@
import React, { useEffect, useState } from "react";
import { OlFrequencyInput } from "../../components/olfrequencyinput";
import { FaTrash } from "react-icons/fa6";
import { OlLabelToggle } from "../../components/ollabeltoggle";
import { OlStateButton } from "../../components/olstatebutton";
import { faEarListen, faMicrophoneLines } from "@fortawesome/free-solid-svg-icons";
import { SRSRadio } from "../../../audio/srsradio";
import { SRSRadioSetting } from "../../../interfaces";
import { getApp } from "../../../olympusapp";
export function RadioPanel(props: { index: number; setting: SRSRadioSetting, onSettingUpdate: (SRSRadioSetting) => void }) {
return (
<div
className={`
flex flex-col content-center justify-between gap-2 rounded-md
bg-olympus-200/30 py-3 pl-4 pr-5
`}
>
<div className="flex content-center justify-between">
<span className="my-auto">Radio {props.index + 1}</span>
<div className="rounded-md bg-red-800 p-2" onClick={() => {getApp().getAudioManager().removeRadio(props.index);}}>
<FaTrash className={`text-gray-50`}></FaTrash>
</div>
</div>
<OlFrequencyInput
value={props.setting.frequency}
onChange={(value) => {
let setting = props.setting;
setting.frequency = value;
props.onSettingUpdate(setting);
}}
/>
<div className="flex flex-row gap-2">
<OlLabelToggle
leftLabel="AM"
rightLabel="FM"
toggled={props.setting.modulation !== 0}
onClick={() => {
let setting = props.setting;
setting.modulation = setting.modulation === 1 ? 0 : 1;
props.onSettingUpdate(setting);
}}
></OlLabelToggle>
<OlStateButton
className="ml-auto"
checked={props.setting.ptt}
icon={faMicrophoneLines}
onClick={() => {
let setting = props.setting;
setting.ptt = !setting.ptt;
props.onSettingUpdate(setting);
}}
tooltip="Talk on frequency"
></OlStateButton>
<OlStateButton
checked={props.setting.tuned}
icon={faEarListen}
onClick={() => {
let setting = props.setting;
setting.tuned = !setting.tuned;
props.onSettingUpdate(setting);
}}
tooltip="Tune to radio"
></OlStateButton>
</div>
</div>
);
}

View File

@@ -1,73 +1,107 @@
import React, { useEffect, useState } from "react";
import { Menu } from "./components/menu";
import { OlCheckbox } from "../components/olcheckbox";
import { OlRangeSlider } from "../components/olrangeslider";
import { OlNumberInput } from "../components/olnumberinput";
import { MapOptions } from "../../types/types";
import { getApp } from "../../olympusapp";
import { OlFrequencyInput } from "../components/olfrequencyinput";
import { OlStateButton } from "../components/olstatebutton";
import { faEarListen, faMicrophoneLines } from "@fortawesome/free-solid-svg-icons";
import { OlLabelToggle } from "../components/ollabeltoggle";
import { FaVolumeHigh } from "react-icons/fa6";
import { OlToggle } from "../components/oltoggle";
import { RadioPanel } from "./components/radiopanel";
import { FaQuestionCircle } from "react-icons/fa";
import { SRSRadioSetting } from "../../interfaces";
export function RadioMenu(props: { open: boolean; onClose: () => void; children?: JSX.Element | JSX.Element[] }) {
const [frequency1, setFrequency1] = useState(251000000);
const [ptt1, setPTT1] = useState(false);
const [frequency2, setFrequency2] = useState(251000000);
const [frequency3, setFrequency3] = useState(243000000);
const [frequency4, setFrequency4] = useState(11200000);
const [radioEnabled, setRadioEnabled] = useState(false);
const [radioSettings, setRadioSettings] = useState([] as SRSRadioSetting[]);
useEffect(() => {
if (getApp()) {
let settings = getApp().getAudioManager().getRadioSettings();
settings[0].frequency = frequency1;
settings[0].ptt = ptt1;
getApp().getAudioManager().setRadioSettings(settings);
}
});
/* Force a rerender */
document.addEventListener("radiosUpdated", () => {
setRadioSettings(
getApp()
?.getAudioManager()
.getRadios()
.map((radio) => radio.getSetting())
);
});
}, []);
return (
<Menu title="Radio" open={props.open} showBackButton={false} onClose={props.onClose}>
<div className="p-4 text-sm text-gray-400">The radio menu allows you to talk on radio to the players online using SRS.</div>
<div className="mx-6 flex rounded-lg bg-olympus-400 p-4 text-sm">
<div>
<FaQuestionCircle className="my-4 ml-2 mr-6 text-gray-400" />
</div>
<div className="flex flex-col gap-1">
<div className="text-gray-100">Use the radio controls to tune to a frequency, then click on the PTT button to talk. </div>
<div className="text-gray-400">You can add up to 10 radios. Use the audio effects menu to play audio tracks or to add background noises.</div>
</div>
</div>
<div
className={`
flex flex-col gap-2 p-5 font-normal text-gray-800
dark:text-white
`}
>
<div
className={`
flex flex-col content-center justify-between gap-2 rounded-md
bg-olympus-200/30 py-3 pl-4 pr-5
`}
>
Radio 1
<OlFrequencyInput
value={frequency1}
onChange={(value) => {
setFrequency1(value);
<div className="flex justify-between">
<span>Enable radio:</span>
<OlToggle
toggled={radioEnabled}
onClick={() => {
radioEnabled ? getApp().getAudioManager().stop() : getApp().getAudioManager().start();
setRadioEnabled(!radioEnabled);
}}
/>
<div className="flex gap-4 py-2">
<FaVolumeHigh className="h-8 w-8 p-1" />
<OlRangeSlider value={50} onChange={() => {}} className="my-auto" />
<span className="my-auto">50</span>
</div>
<div className="flex flex-row gap-2">
<OlLabelToggle leftLabel="AM" rightLabel="FM" toggled={false} onClick={() => {}}></OlLabelToggle>
<OlStateButton
className="ml-auto"
checked={ptt1}
icon={faMicrophoneLines}
onClick={() => {
setPTT1(!ptt1);
}}
tooltip="Talk on frequency"
></OlStateButton>
<OlStateButton checked={false} icon={faEarListen} onClick={() => {}} tooltip="Tune to radio"></OlStateButton>
</div>
</div>
{radioEnabled && radioSettings.map((setting, idx) => {
return (
<RadioPanel
index={idx}
setting={setting}
onSettingUpdate={(setting) => {
getApp().getAudioManager().getRadios()[idx].setSetting(setting);
}}
></RadioPanel>
);
})}
{radioEnabled && radioSettings.length < 10 && (
<button
type="button"
className={`
mb-2 me-2 rounded-lg bg-blue-700 px-5 py-2.5 text-sm font-medium
text-white
dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800
focus:outline-none focus:ring-4 focus:ring-blue-300
hover:bg-blue-800
`}
onClick={() => getApp().getAudioManager().addRadio()}
>
Add radio
</button>
)}
</div>
</Menu>
);
}
/*
{refreshSources >= 0 &&
getApp()
?.getAudioManager()
.getSources()
.map((source, idx) => {
return <AudioSourcePanel index={idx} source={source} />;
})}
<button
onClick={() => {
var input = document.createElement("input");
input.type = "file";
input.click();
input.onchange = (e: Event) => {
let target = e.target as HTMLInputElement;
if (target && target.files) {
var file = target.files[0];
getApp().getAudioManager().addFileSource(file);
}
};
}}
>
Add audio source
</button> */