Initial commit
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<div class="noise-controlled-band">
|
||||
<AudioTag
|
||||
:ref="el => audioElement"
|
||||
:src="audioSrc"
|
||||
:volume="volume"
|
||||
:play="playing"
|
||||
@canplay="onCanPlay"
|
||||
/>
|
||||
<RNBOControlValue
|
||||
:center-frequency="centerFrequency"
|
||||
:status="playing"
|
||||
:q-factor="$props.qFactor"
|
||||
:attack="masterAttack"
|
||||
:release="masterRelease"
|
||||
@control-value-change="handleValueChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, computed } from 'vue'
|
||||
import AudioTag from '../../AudioTag.vue'
|
||||
import RNBOControlValue from '../..//tests/ControlValues/RNBOControlValue.vue'
|
||||
import tracksConfig from '~/tracks.config'
|
||||
import { useAudioStore } from '~/stores/audio'
|
||||
import { calculateNormalizedVolume } from '~/lib/AudioFunctions'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'NoiseControlledBand',
|
||||
components: {
|
||||
AudioTag,
|
||||
RNBOControlValue
|
||||
},
|
||||
props: {
|
||||
centerFrequency: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
qFactor: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
masterAttack: {
|
||||
type: Number,
|
||||
default: 120000,
|
||||
required: false
|
||||
},
|
||||
masterRelease: {
|
||||
type: Number,
|
||||
default: 144000,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
emits: ['ready', 'update:mid-volume'],
|
||||
setup (props, { emit }) {
|
||||
const audioElement = ref<InstanceType<typeof HTMLElement> | null>(null)
|
||||
const playing = computed(() => { return useAudioStore().playing }) // the playing state is bind to the audioStore
|
||||
const gainValueDB = ref(0)
|
||||
const volume = ref(0)
|
||||
const audioSrc = computed(() => {
|
||||
try {
|
||||
const frequency = props.centerFrequency
|
||||
|
||||
let band = ''
|
||||
if (frequency < 500) {
|
||||
band = 'low_band'
|
||||
} else if (frequency >= 500 && frequency < 4000) {
|
||||
band = 'mid_band'
|
||||
} else {
|
||||
band = 'high_band'
|
||||
}
|
||||
|
||||
const path = `/masking/3bands/${band}_256kbps.webm`
|
||||
const fullPath = `${window.location.origin}${encodeURI(path)}`
|
||||
|
||||
useNuxtApp().$logger.info('Loading audio track:', fullPath)
|
||||
|
||||
return fullPath
|
||||
} catch (error) {
|
||||
useNuxtApp().$logger.error('Error loading audio track:', error)
|
||||
return ''
|
||||
}
|
||||
})
|
||||
|
||||
const handleValueChange = (data: { frequency: number; value: number }) => {
|
||||
// Convert dB to linear scale
|
||||
gainValueDB.value = calculateNormalizedVolume(data.value)
|
||||
volume.value = gainValueDB.value
|
||||
emit('update:mid-volume', volume.value)
|
||||
}
|
||||
|
||||
const onCanPlay = () => {
|
||||
emit('ready', props.centerFrequency)
|
||||
}
|
||||
|
||||
return {
|
||||
audioElement,
|
||||
audioSrc,
|
||||
gainValueDB,
|
||||
volume,
|
||||
handleValueChange,
|
||||
onCanPlay,
|
||||
playing
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.noise-controlled-band {
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<div class="noise-controlled-band">
|
||||
<AudioTag
|
||||
:ref="el => audioElement"
|
||||
:src="audioSrc"
|
||||
:volume="volume"
|
||||
:play="playing"
|
||||
@canplay="onCanPlay"
|
||||
/>
|
||||
<RNBOControlValue
|
||||
:center-frequency="centerFrequency"
|
||||
:status="playing"
|
||||
:attack="masterAttack"
|
||||
:release="masterRelease"
|
||||
@control-value-change="handleValueChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, computed } from 'vue'
|
||||
import AudioTag from '../../AudioTag.vue'
|
||||
import RNBOControlValue from '../../tests/ControlValues/RNBOControlValue.vue'
|
||||
import tracksConfig from '~/tracks.config'
|
||||
import { useAudioStore } from '~/stores/audio'
|
||||
import { calculateNormalizedVolume } from '~/lib/AudioFunctions'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'NoiseControlledBand',
|
||||
components: {
|
||||
AudioTag,
|
||||
RNBOControlValue
|
||||
},
|
||||
props: {
|
||||
centerFrequency: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
masterAttack: {
|
||||
type: Number,
|
||||
default: 120000,
|
||||
required: false
|
||||
},
|
||||
masterRelease: {
|
||||
type: Number,
|
||||
default: 144000,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
emits: ['ready'],
|
||||
setup (props, { emit }) {
|
||||
const audioElement = ref<InstanceType<typeof HTMLElement> | null>(null)
|
||||
const playing = computed(() => { return useAudioStore().playing }) // the playing state is bind to the audioStore
|
||||
const gainValueDB = ref(0)
|
||||
const volume = ref(0)
|
||||
const audioSrc = computed(() => {
|
||||
try {
|
||||
const frequencyKey = `${props.centerFrequency}_src`
|
||||
useNuxtApp().$logger.log('Loading audio track:', frequencyKey)
|
||||
const trackPath = tracksConfig[frequencyKey as keyof typeof tracksConfig]
|
||||
if (!trackPath) {
|
||||
throw new Error(`No track found for frequency ${props.centerFrequency}`)
|
||||
}
|
||||
const returnValue = `${window.location.origin}${encodeURI(trackPath)}`
|
||||
// Check if the audio file is available
|
||||
return returnValue
|
||||
} catch (error) {
|
||||
useNuxtApp().$logger.error('Error loading audio track:', error)
|
||||
return ''
|
||||
}
|
||||
})
|
||||
|
||||
const handleValueChange = (data: { frequency: number; value: number }) => {
|
||||
// Convert dB to linear scale
|
||||
|
||||
gainValueDB.value = calculateNormalizedVolume(data.value)
|
||||
volume.value = gainValueDB.value
|
||||
}
|
||||
|
||||
const onCanPlay = () => {
|
||||
useNuxtApp().$logger.log(`Audio for frequency ${props.centerFrequency} is ready to play`)
|
||||
emit('ready', props.centerFrequency)
|
||||
}
|
||||
|
||||
return {
|
||||
audioElement,
|
||||
audioSrc,
|
||||
gainValueDB,
|
||||
volume,
|
||||
handleValueChange,
|
||||
onCanPlay,
|
||||
playing
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.noise-controlled-band {
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div v-show="false" id="hiddenAudio">
|
||||
<AudioTagWebAudio
|
||||
ref="audioElement"
|
||||
:src="audioSrc"
|
||||
:volume="volume"
|
||||
:play="playing"
|
||||
:master-gain="masterGain"
|
||||
@canplay="onCanPlay"
|
||||
/>
|
||||
<div class="noise-controlled-band">
|
||||
Gain: {{ gainValueDB }}
|
||||
<RNBOControlValue
|
||||
:center-frequency="centerFrequency"
|
||||
:status="playing"
|
||||
:attack="masterAttack"
|
||||
:release="masterRelease"
|
||||
:q-factor="qFactor"
|
||||
@control-value-change="handleValueChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, computed } from 'vue'
|
||||
import type { Logger } from 'pino'
|
||||
import RNBOControlValue from '../../tests/ControlValues/RNBOControlValue.vue'
|
||||
import AudioTagWebAudio from '../../AudioTagWebAudio.vue'
|
||||
import { calculateNormalizedVolume } from '~/lib/AudioFunctions'
|
||||
import { useAudioStore } from '~/stores/audio'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'NoiseControlledWebAudio3Band',
|
||||
components: {
|
||||
AudioTagWebAudio,
|
||||
RNBOControlValue
|
||||
},
|
||||
props: {
|
||||
centerFrequency: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
masterGain: {
|
||||
type: GainNode,
|
||||
required: true
|
||||
},
|
||||
masterAttack: {
|
||||
type: Number,
|
||||
default: 120000 * 2,
|
||||
required: false
|
||||
},
|
||||
masterRelease: {
|
||||
type: Number,
|
||||
default: 144000 / 1000,
|
||||
required: false
|
||||
},
|
||||
qFactor: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
emits: ['ready'],
|
||||
setup (props, { emit }) {
|
||||
const audioElement = ref<InstanceType<typeof HTMLElement> | null>(null)
|
||||
const gainValueDB = ref(0)
|
||||
const volume = ref(1)
|
||||
const playing = computed(() => { return useAudioStore().getPlaying }) // the playing state is bind to the audioStore
|
||||
const logger = useNuxtApp().$logger as Logger
|
||||
const audioSrc = computed(() => {
|
||||
try {
|
||||
const frequency = props.centerFrequency
|
||||
|
||||
let band = ''
|
||||
if (frequency < 500) {
|
||||
band = 'low_band'
|
||||
} else if (frequency >= 500 && frequency < 4000) {
|
||||
band = 'mid_band'
|
||||
} else {
|
||||
band = 'high_band'
|
||||
}
|
||||
|
||||
const path = `/masking/3bands/${band}_256kbps.webm`
|
||||
const fullPath = `${window.location.origin}${encodeURI(path)}`
|
||||
return fullPath
|
||||
} catch (error) {
|
||||
return ''
|
||||
}
|
||||
})
|
||||
const handleValueChange = (data: { frequency: number; value: number }) => {
|
||||
// Convert dB to linear scale
|
||||
gainValueDB.value = calculateNormalizedVolume(data.value)
|
||||
volume.value = gainValueDB.value
|
||||
}
|
||||
|
||||
const onCanPlay = () => {
|
||||
logger.info(`Audio for frequency ${props.centerFrequency} is ready to play`)
|
||||
emit('ready', props.centerFrequency)
|
||||
}
|
||||
|
||||
return {
|
||||
audioElement,
|
||||
audioSrc,
|
||||
gainValueDB,
|
||||
volume,
|
||||
handleValueChange,
|
||||
onCanPlay,
|
||||
playing
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.noise-controlled-band {
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
@@ -0,0 +1,111 @@
|
||||
<template>
|
||||
<div class="noise-controlled-band">
|
||||
<AudioTagWebAudio
|
||||
ref="audioElement"
|
||||
:src="audioSrc"
|
||||
:volume="volume"
|
||||
:play="playing"
|
||||
:master-gain="masterGain"
|
||||
@canplay="onCanPlay"
|
||||
/>
|
||||
Gain: {{ gainValueDB }}
|
||||
<RNBOControlValue
|
||||
:center-frequency="centerFrequency"
|
||||
:status="playing"
|
||||
:attack="masterAttack"
|
||||
:release="masterRelease"
|
||||
@control-value-change="handleValueChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, computed } from 'vue'
|
||||
import type { Logger } from 'pino'
|
||||
import RNBOControlValue from '../..//tests/ControlValues/RNBOControlValue.vue'
|
||||
import AudioTagWebAudio from '../../AudioTagWebAudio.vue'
|
||||
import tracksConfig from '~/tracks.config'
|
||||
import { calculateNormalizedVolume } from '~/lib/AudioFunctions'
|
||||
import { useAudioStore } from '~/stores/audio'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'NoiseControlledWebAudioBand',
|
||||
components: {
|
||||
AudioTagWebAudio,
|
||||
RNBOControlValue
|
||||
},
|
||||
props: {
|
||||
centerFrequency: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
masterGain: {
|
||||
type: GainNode,
|
||||
required: true
|
||||
},
|
||||
masterAttack: {
|
||||
type: Number,
|
||||
default: 120000,
|
||||
required: false
|
||||
},
|
||||
masterRelease: {
|
||||
type: Number,
|
||||
default: 144000,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
emits: ['ready'],
|
||||
setup (props, { emit }) {
|
||||
const audioElement = ref<InstanceType<typeof HTMLElement> | null>(null)
|
||||
const gainValueDB = ref(0)
|
||||
const volume = ref(1)
|
||||
const playing = computed(() => { return useAudioStore().playing }) // the playing state is bind to the audioStore
|
||||
const logger = useNuxtApp().$logger as Logger
|
||||
const audioSrc = computed(() => {
|
||||
try {
|
||||
const frequencyKey = `${props.centerFrequency}_src`
|
||||
logger.info('Loading audio track:', frequencyKey)
|
||||
const trackPath = tracksConfig[frequencyKey as keyof typeof tracksConfig]
|
||||
if (!trackPath) {
|
||||
throw new Error(`No track found for frequency ${props.centerFrequency}`)
|
||||
}
|
||||
const returnValue = `${window.location.origin}${encodeURI(trackPath)}`
|
||||
// Check if the audio file is available
|
||||
return returnValue
|
||||
} catch (error) {
|
||||
logger.error('Error loading audio track:', error)
|
||||
return ''
|
||||
}
|
||||
})
|
||||
const handleValueChange = (data: { frequency: number; value: number }) => {
|
||||
// Convert dB to linear scale
|
||||
gainValueDB.value = calculateNormalizedVolume(data.value)
|
||||
volume.value = gainValueDB.value
|
||||
}
|
||||
|
||||
const onCanPlay = () => {
|
||||
logger.info(`Audio for frequency ${props.centerFrequency} is ready to play`)
|
||||
emit('ready', props.centerFrequency)
|
||||
}
|
||||
|
||||
return {
|
||||
audioElement,
|
||||
audioSrc,
|
||||
gainValueDB,
|
||||
volume,
|
||||
handleValueChange,
|
||||
onCanPlay,
|
||||
playing
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.noise-controlled-band {
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
316
components/experiments/tests/ControlValues/RNBOControlValue.vue
Normal file
316
components/experiments/tests/ControlValues/RNBOControlValue.vue
Normal file
@@ -0,0 +1,316 @@
|
||||
<!--
|
||||
RNBOControlValue ist eine Komponente zur Steuerung und Überwachung von Audio-Parametern,
|
||||
insbesondere für die Kontrolle von Frequenzbändern. Sie ermöglicht das Testen von
|
||||
Audio-Geräten, die Anpassung von Parametern und die Anzeige von Kontrollwerten in Echtzeit.
|
||||
-->
|
||||
<template>
|
||||
<div v-if="true">
|
||||
<h2>Control Values Device Test -- {{ centerFrequency }}Hz</h2>
|
||||
<button @click="testControlValuesDevice">Test Control Values Device</button>
|
||||
<p v-if="testResult">{{ testResult }}</p>
|
||||
<div class="microphone-info">
|
||||
<h3>Current Microphone:</h3>
|
||||
<p>{{ currentMicrophone || 'No microphone selected' }}</p>
|
||||
</div>
|
||||
|
||||
<table v-if="parameters.length > 0" class="parameter-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Parameter Name</th>
|
||||
<th>Value</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="param in parameters" :key="param.name">
|
||||
<td>{{ param.name }}</td>
|
||||
<td>
|
||||
<input
|
||||
:value="param.value"
|
||||
type="number"
|
||||
@input="updateParameter(param.name, $event.target?.value)"
|
||||
>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
:value="param.value"
|
||||
type="range"
|
||||
:min="param.min"
|
||||
:max="param.max"
|
||||
:step="param.step"
|
||||
@input="updateParameter(param.name, $event.target?.value)"
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- Neue Keynote für den Outlet-Wert -->
|
||||
<div class="outlet-keynote">
|
||||
<h3>Control Value</h3>
|
||||
<div class="outlet-value">{{ formatValue(outletValue) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { mapActions, mapState } from 'pinia'
|
||||
import { useDevicesStore } from '~/stores/device'
|
||||
import { useMicStore } from '~/stores/microphone'
|
||||
import { useAudioStore } from '~/stores/audio'
|
||||
|
||||
interface ParameterData {
|
||||
name: string;
|
||||
paramId: string;
|
||||
value: number;
|
||||
min: number;
|
||||
max: number;
|
||||
step: number;
|
||||
}
|
||||
|
||||
const minSamples = 48
|
||||
const maxSamples = 1920000
|
||||
|
||||
export default defineComponent({
|
||||
name: 'RNBOControlValue',
|
||||
props: {
|
||||
centerFrequency: {
|
||||
type: Number,
|
||||
required: true,
|
||||
validator: (value: number) => [63, 125, 250, 500, 1000, 1500, 2000, 4000, 8000, 16000, 150].includes(value)
|
||||
},
|
||||
qFactor: {
|
||||
type: Number,
|
||||
default: 1.414,
|
||||
validator: (value: number) => value > 0.1 && value < 1.5
|
||||
},
|
||||
attack: {
|
||||
type: Number,
|
||||
default: 120000,
|
||||
validator: (value:number) => value >= minSamples && value <= maxSamples
|
||||
},
|
||||
release: {
|
||||
type: Number,
|
||||
default: 144000,
|
||||
validator: (value:number) => value >= minSamples && value <= maxSamples
|
||||
},
|
||||
status: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
emits: ['control-value-change'],
|
||||
data () {
|
||||
return {
|
||||
testResult: '',
|
||||
parameters: [] as ParameterData[],
|
||||
device: null as any,
|
||||
outletValue: 0,
|
||||
currentMicrophone: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useMicStore, ['microphone'])
|
||||
},
|
||||
watch: {
|
||||
release (value) {
|
||||
this.updateParameter('release', '' + value)
|
||||
},
|
||||
attack (value) {
|
||||
if (!isNaN(value)) {
|
||||
this.updateParameter('attack', '' + value)
|
||||
}
|
||||
},
|
||||
status (newStatus) {
|
||||
const microphoneStore = useMicStore()
|
||||
// status is bind to playing status in audio store
|
||||
if (newStatus) {
|
||||
microphoneStore.attachMicrophone()
|
||||
this.testControlValuesDevice()
|
||||
} else {
|
||||
microphoneStore.detachMicrophone()
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
mounted () {
|
||||
this.updateParameter('centerFrequency', '' + this.centerFrequency)
|
||||
this.updateParameter('release', '' + this.release)
|
||||
this.updateParameter('attack', '' + this.attack)
|
||||
this.updateParameter('qFactor', String(this.qFactor))
|
||||
},
|
||||
methods: {
|
||||
async getCurrentMicrophone () {
|
||||
const micStore = useMicStore()
|
||||
|
||||
try {
|
||||
const micro = await micStore.getMicrophone()
|
||||
if (micro?.microphoneNode.label) {
|
||||
this.currentMicrophone = micro.microphoneNode.label
|
||||
} else {
|
||||
this.currentMicrophone = 'No microphone detected'
|
||||
}
|
||||
} catch (error) {
|
||||
useNuxtApp().$logger.error('Error getting microphone:', error)
|
||||
this.currentMicrophone = 'Error detecting microphone'
|
||||
}
|
||||
},
|
||||
async testControlValuesDevice () {
|
||||
const deviceStore = useDevicesStore()
|
||||
const micStore = useMicStore()
|
||||
const audioStore = useAudioStore()
|
||||
|
||||
await audioStore.getContext()
|
||||
if (!audioStore) { return }
|
||||
if (audioStore.audioContext?.state !== 'running') {
|
||||
await audioStore.audioContext?.resume()
|
||||
}
|
||||
this.device = await deviceStore.createControlValuesDevice(`testControlValues_${this.centerFrequency}Hz`, this.centerFrequency)
|
||||
if (!this.device) {
|
||||
this.testResult = `Failed to create control values device for ${this.centerFrequency}Hz`
|
||||
// this.$logger.error('Device creation failed')
|
||||
}
|
||||
const device = this.device
|
||||
// this.$logger.info(`Created device for ${this.centerFrequency}Hz`, { device })
|
||||
const microphone = await micStore.getMicrophone()
|
||||
|
||||
try {
|
||||
const micSource = microphone.microphoneNode
|
||||
if (micSource && this.device.node && audioStore.audioContext) {
|
||||
micSource.connect(this.device.node)
|
||||
await this.updateParameterList()
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 100))
|
||||
|
||||
this.setupOutletListener()
|
||||
this.testResult = `Control values device for ${this.centerFrequency}Hz created successfully`
|
||||
} else {
|
||||
this.testResult = `Failed to connect microphone to device for ${this.centerFrequency}Hz`
|
||||
// this.$logger.error('Connection failed:', { micSource, deviceNode: this.device.node, audioContext: audioStore.audioContext })
|
||||
}
|
||||
} catch (error) {
|
||||
// this.$logger.error(`Test failed for ${this.centerFrequency}Hz:`, error)
|
||||
this.testResult = `Test failed for ${this.centerFrequency}Hz: ${error instanceof Error ? error.message : String(error)}`
|
||||
// this.$logger.error(this.testResult)
|
||||
}
|
||||
},
|
||||
setupOutletListener () {
|
||||
try {
|
||||
if (!this.device) {
|
||||
// this.$logger.warn('Device is not available')
|
||||
return
|
||||
}
|
||||
this.device.messageEvent.subscribe((ev: any) => {
|
||||
if (ev.tag === 'out1') {
|
||||
const newValue = this.ensureNumber(ev.payload)
|
||||
this.outletValue = newValue
|
||||
if (!(newValue > -13 && newValue < -12.98)) {
|
||||
this.$emit('control-value-change', { frequency: this.centerFrequency, value: newValue })
|
||||
}
|
||||
}
|
||||
})
|
||||
} catch (error: unknown) {
|
||||
// this.$logger.error(`Test failed for ${this.centerFrequency}Hz:`, error)
|
||||
this.testResult = `Test failed for ${this.centerFrequency}Hz: ${error instanceof Error ? error.message : String(error)}`
|
||||
}
|
||||
},
|
||||
updateParameterList () {
|
||||
// this.$logger.info('Updating parameter list', this.device)
|
||||
if (this.device && this.device.parameters) {
|
||||
const params = this.device.parameters
|
||||
// this.$logger.info('Parameters:', { params })
|
||||
|
||||
this.parameters = Array.from(params.entries()).map(([name, param]: [string, any]) => {
|
||||
return {
|
||||
name: param.name,
|
||||
value: this.ensureNumber(param.value),
|
||||
min: this.ensureNumber(param.min),
|
||||
max: this.ensureNumber(param.max),
|
||||
step: this.ensureNumber(param.step) || 0.01
|
||||
}
|
||||
})
|
||||
|
||||
// this.$logger.info('Updated parameters:', this.parameters)
|
||||
} else {
|
||||
// this.$logger.info('No parameters found')
|
||||
}
|
||||
},
|
||||
updateParameter (name: string, value: string) {
|
||||
if (this.device && this.device.parameters) {
|
||||
const numValue = this.ensureNumber(value)
|
||||
const param = this.parameters.find(p => p.name === name)
|
||||
|
||||
if (param) {
|
||||
param.value = numValue
|
||||
|
||||
if (typeof this.device.parameters.set === 'function') {
|
||||
this.device.parameters.set(name, numValue)
|
||||
} else if (Array.isArray(this.device.parameters)) {
|
||||
const deviceParam = this.device.parameters.find((p: any) => p.name === name)
|
||||
if (deviceParam) {
|
||||
deviceParam.value = numValue
|
||||
}
|
||||
} else if (typeof this.device.parameters === 'object') {
|
||||
if (this.device.parameters[name]) {
|
||||
this.device.parameters[name].value = numValue
|
||||
}
|
||||
}
|
||||
this.$forceUpdate()
|
||||
}
|
||||
} else {
|
||||
// Device noch nicht da → update nur in local parameters
|
||||
const param = this.parameters.find(p => p.name === name)
|
||||
if (param) {
|
||||
param.value = this.ensureNumber(value)
|
||||
} else {
|
||||
this.parameters.push({ name, value: this.ensureNumber(value) })
|
||||
}
|
||||
this.$forceUpdate()
|
||||
}
|
||||
},
|
||||
ensureNumber (value: any): number {
|
||||
const num = Number(value)
|
||||
return isNaN(num) ? 0 : num
|
||||
},
|
||||
formatValue (value: number): string {
|
||||
return value.toFixed(2)
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.parameter-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.parameter-table th, .parameter-table td {
|
||||
border: 1px solid #ddd;
|
||||
padding: 8px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.parameter-table th {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
.parameter-table input[type="range"] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.outlet-keynote {
|
||||
text-align: center;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.outlet-keynote h3 {
|
||||
font-size: 1.2em;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.outlet-value {
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user