> For the complete documentation index, see [llms.txt](https://nccr-liri.gitbook.io/annotation-web-interface-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://nccr-liri.gitbook.io/annotation-web-interface-docs/technical/track.md).

# Track

The track component is where audio is visualized as a spectrogram and waveform and where the user annotates the actual audio. Each track represents one channel of the uploaded audio file, e.g. uploading a stereo file will create two new tracks. Each track also contains a side-bar with user controls and a so called labels canvas, to display the labels, as well as an individuals canvas to display the individuals. Let's have a look at some key variables.

```jsx
// General
const [audioId, setAudioId] = useState(trackData.audioID)
const audioIdRef = useRef(labelsStorage.get(`${trackID}_audioID`) || trackData.audioID)
```

`audioId` is a unique identifier for the audio channel inside this track. It is generated and returned by the backend.

`audioIdRef` is the same but as React reference object to persists across app remounts.

```jsx
// Spectrogram
const specCanvasRef = useRef(null)
const specImgData = useRef(null)
const [spectrogram, setSpectrogram] = useState(trackData.spectrogram)
```

`specCanvasRef` is the reference object to tie the spectrogram canvas into the DOM.&#x20;

`specImgData` is another reference object that tracks the content of that canvas (think of it as a screenshot). This value will used for functions that refresh the canvas many times in a row but the underlying spectrogram remains unchanged (e.g. dragging or hovering labels), instead of making a request to the backend to compute a new spectrogram each time.

`spectrogram` tracks the state of the most recent returned spectrogram from the backend. This value is updated any time a spectrogram is recomputed by the backend (e.g. zoom, scroll and audio upload events).

```jsx
// Frequency
const frequenciesCanvasRef = useRef(null)
const [frequencies, setFrequencies] = useState(trackData.frequencies)
const frequenciesRef = useRef(frequencies)
const [showFrequencyLines, setShowFrequencyLines] = useState(false)

const [frequencyLines, setFrequencyLines] = useState({maxFreqY: -10, minFreqY: specCanvasHeight+10})
const frequencyLinesRef = useRef({maxFreqY: -10, minFreqY: specCanvasHeight+10})
const [frequencyRanges, setfrequencyRanges] = useState( null )

let draggedFrequencyLinesObject = null
```

`frequenciesCanvasRef` is the reference object to tie the frequencies canvas into the DOM.

`frequencies` tracks the state of the most recent returned frequencies array from the backend. This value is updated any time a new frequency Array is returned by the backend (e.g. when the user changes the frequency range or uploads new audio).

`frequenciesRef` keeps the ref in sync with the state across remounts.

`showFrequencyLines` is a boolean that, set to true, toggles on the display of the min- and max-frequency lines in the spectrogram canvas.

`frequencyLines` is an object that keeps track of the Y position of both both frequency lines (this is a pixel value, not the actual frequency).

`draggedFrequencyLinesObject` is a copy of `frequencyLines` it used to update the values in real-time when dragging the frequency lines, instead of setting the state of `frequencyLines` asynchronously.&#x20;

```jsx
// Labels and Individuals Canvases
const [showLabelAndIndividualsCanvas, setShowLabelAndIndividualsCanvas] = useState(true)  
```

`showLabelAndIndividualsCanvas` is a boolean that, set to true, toggles on the display of the individuals and label canvas.

```jsx
// Label Canvas
const labelCanvasRef = useRef(null)
```

`labelCanvasRef` is the reference object to tie the label canvas into the DOM.

```jsx
// Individuals Canvas
const individualsCanvasRef = useRef(null)
const numberOfIndividuals = speciesArray.reduce((total, speciesObj) => total + speciesObj.individuals.length, 0)
```

`individualsCanvasRef` is the reference object to tie the individuals canvas into the DOM.

`numberOfIndividuals` is an integer that is used to calculate the height of the individuals canvas.

```jsx
// Labels
const labelsRef = useRef([])
const [activeLabel, setActiveLabel] = useState(null)
let draggedActiveLabel = null
let clickedLabel = undefined
let lastHoveredLabel = {labelObject: null, isHighlighted: false}
```

`labelsRef` is an array that stores all label objects of this track.

`activeLabel` is the object that tracks which label is currently selected. It is used in other tracks to extend the onset and offset of the active label to those sibling components.

`draggedActiveLabel` is a copy of `activeLabel` that is being updated in real-time when the user drags the onset or offset of the active label, to allow a smooth animation.&#x20;

`clickedLabel` is a copy of the currently selected label that is being updated in real-time when the user drags the onset or offset of that label, to allow a smooth animation.&#x20;

`lastHoveredLabel` is an object that stores the currently hovered label, which is being rendered separately to the labels that are not being hovered

```jsx
// Audio
const playheadRef = useRef(new Playhead(0))
const [audioSnippet, setAudioSnippet] = useState(null)
const [playWindowTimes, setPlayWindowTimes] = useState(null)
```

`playheadRef` is a reference object that stores an instance of the Playhead class. This custom class is used to update the playhead when playing the audio in real-time for a smooth animation.

`audioSnippet` stores the sound file of the audio visible in the current track viewport, when the user requests to playback the audio.

`playWindowTimes` is an object that stores the start- and end-time of the audio snippet.

```jsx
// Waveform
const waveformCanvasRef = useRef(null)
const waveformImgData = useRef(null)
const [audioArray, setAudioArray] = useState(null)
const [waveformScale, setWaveformScale] = useState(25)
const [showWaveform, setShowWaveform] =  useState(true)
```

`waveformCanvasRef` is the reference object to tie the waveform canvas into the DOM.

`waveformImgData` is another reference object that tracks the content of that canvas (think of it as a screenshot). This value will used for functions that refresh the canvas many times in a row but the underlying waveform remains unchanged (e.g. dragging or hovering labels), instead of making a request to the backend to compute a new waveform each time.

`audioArray` is an array of data points returned by the backend used to draw the waveform.

`waveformScale` is a value to set the waveforms height (in both directions).

`showWaveform` is a boolean that, set to true, toggles on the display of the waveform canvas.

```jsx
// File Upload
const [spectrogramIsLoading, setSpectrogramIsLoading] = useState(false)
```

`spectrogramIsLoading` is a boolean that conditionally renders various animations, buttons and elements on the page while the spectrogram is being computed by the backend.

```jsx
// Local Parameters
const [showLocalConfigWindow, setShowLocalConfigWindow] = useState(false)
const [specCalMethod, setSpecCalMethod] = useState(trackData.specCalMethod ? trackData.specCalMethod : 'linear')
const [nfft, setNfft] = useState(trackData.nfft ? trackData.nfft : '')
const [binsPerOctave, setBinsPerOctave] = useState(trackData.binsPerOctave ? trackData.binsPerOctave: '')
const [minFreq, setMinFreq] = useState(trackData.minFreq ? trackData.minFreq : '')
const [maxFreq, setMaxFreq] = useState(trackData.maxFreq ? trackData.maxFreq : '')
```

`showLocalConfigWindow` is a boolean that, set to true, toggles on the display of the Local Configurations Window.

`specCalMethod`, `nfft`, `binsPerOctave`, `minFreq` and `maxFreq` track the current state of their corresponding input fields and radio buttons inside the local config window.

```jsx
// WhisperSeg
const [whisperSegIsLoading, setWhisperSegIsLoading] = useState(false)
```

`whisperSegIsLoading` is a boolean that conditionally renders a loading bar while WhisperSeg is annotating the audio.

```jsx
// Active Species
const activeSpecies = speciesArray.find(speciesObj =>
    speciesObj.individuals.some(individual => individual.isActive)
)
```

`activeSpecies` keeps track of the currently selected species in the species menu. Active means that any labels being made while be attributed to this species.

```jsx
// Label Window
const [expandedLabel, setExpandedLabel] = useState(null)
const [globalMouseCoordinates, setGlobalMouseCoordinates] = useState(null)
```

`expandedLabel` keeps track of the current label expanded in the label window.

`globalMouseCoordinates` keep track of the users mouse position when he clicked on a label to expand it. These coordinates are being used to render the label window at this mouse position.

```jsx
// Icons
const activeIcon = showWaveform ? icon : iconSmall
const activeIconBtnStyle = showWaveform ? iconBtn : iconBtnSmall
```

`activeIcon` keeps track of the currently active Icon style. Regular icons when the waveform is rendered, small icons when it's hidden, so all icons fit into the now smaller track sidebar.

`activeIconBtnStyle` keeps track of the currently active Icon button style. Regular button styles when the waveform is rendered, small button styles when it's hidden, so all buttons fit into the now smaller track sidebar.

```jsx
// Scroll Context
const { setAnyWindowsOpen } = useOpenWindowsContext()
```

`setAnyWindowsOpen` updates the `OpenWindowsContext` object in `OpenWindowsContext.jsx`. This value is used to keep track of open windows inside `Track.jsx` and temporarily disable the arrow key scroll events in `App.jsx`, so that the user can use the arrow keys inside the open windows input fields without triggering a scroll call.
