mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-08 02:17:25 +02:00
Merge c4e805d049 into 52135913d4
This commit is contained in:
commit
c852f9ddaa
2 changed files with 75 additions and 4 deletions
|
|
@ -9,6 +9,24 @@ import { calculateGain } from '../utils/calculateReplayGain'
|
|||
const llFormats = new Set(config.losslessFormats.split(','))
|
||||
const placeholder = 'N/A'
|
||||
|
||||
// Lossless streams have no meaningful bitrate to show, so their quality is
|
||||
// described by the PCM characteristics instead: `FLAC 96/24`.
|
||||
const formatSampleRate = (sampleRate) => {
|
||||
const khz = sampleRate / 1000
|
||||
return Number.isInteger(khz) ? String(khz) : khz.toFixed(1)
|
||||
}
|
||||
|
||||
const losslessDetail = (sampleRate, bitDepth) => {
|
||||
// DSD carries a 1-bit stream at MHz rates, where `2822.4/1` would say
|
||||
// nothing useful. Those formats keep showing the container alone until
|
||||
// modulation gets its own representation.
|
||||
if (bitDepth === 1 || !(sampleRate > 0)) {
|
||||
return ''
|
||||
}
|
||||
const rate = formatSampleRate(sampleRate)
|
||||
return bitDepth > 0 ? `${rate}/${bitDepth}` : rate
|
||||
}
|
||||
|
||||
const useStyle = makeStyles(
|
||||
(theme) => ({
|
||||
chip: {
|
||||
|
|
@ -30,14 +48,27 @@ export const QualityInfo = ({
|
|||
isDirectPlay,
|
||||
}) => {
|
||||
const classes = useStyle()
|
||||
let { suffix, bitRate, rgAlbumGain, rgAlbumPeak, rgTrackGain, rgTrackPeak } =
|
||||
record
|
||||
let {
|
||||
suffix,
|
||||
bitRate,
|
||||
sampleRate,
|
||||
bitDepth,
|
||||
rgAlbumGain,
|
||||
rgAlbumPeak,
|
||||
rgTrackGain,
|
||||
rgTrackPeak,
|
||||
} = record
|
||||
let info = placeholder
|
||||
|
||||
if (suffix) {
|
||||
suffix = suffix.toUpperCase()
|
||||
info = suffix
|
||||
if (!llFormats.has(suffix) && bitRate > 0) {
|
||||
if (llFormats.has(suffix)) {
|
||||
const detail = losslessDetail(sampleRate, bitDepth)
|
||||
if (detail) {
|
||||
info += ' ' + detail
|
||||
}
|
||||
} else if (bitRate > 0) {
|
||||
info += ' ' + bitRate
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,51 @@ import { QualityInfo } from './QualityInfo'
|
|||
describe('<QualityInfo />', () => {
|
||||
afterEach(cleanup)
|
||||
|
||||
it('only render suffix for lossless formats', () => {
|
||||
it('only renders suffix for lossless formats without stream details', () => {
|
||||
const info = { suffix: 'FLAC', bitRate: 1008 }
|
||||
render(<QualityInfo record={info} />)
|
||||
expect(screen.getByText('FLAC')).toBeInTheDocument()
|
||||
})
|
||||
it('renders sample rate and bit depth for lossless formats', () => {
|
||||
const info = {
|
||||
suffix: 'FLAC',
|
||||
bitRate: 1008,
|
||||
sampleRate: 96000,
|
||||
bitDepth: 24,
|
||||
}
|
||||
render(<QualityInfo record={info} />)
|
||||
expect(screen.getByText('FLAC 96/24')).toBeInTheDocument()
|
||||
})
|
||||
it('renders CD quality without a trailing zero', () => {
|
||||
const info = { suffix: 'FLAC', sampleRate: 44100, bitDepth: 16 }
|
||||
render(<QualityInfo record={info} />)
|
||||
expect(screen.getByText('FLAC 44.1/16')).toBeInTheDocument()
|
||||
})
|
||||
it('keeps one decimal for rates that are not whole kHz', () => {
|
||||
const info = { suffix: 'FLAC', sampleRate: 88200, bitDepth: 24 }
|
||||
render(<QualityInfo record={info} />)
|
||||
expect(screen.getByText('FLAC 88.2/24')).toBeInTheDocument()
|
||||
})
|
||||
it('renders the sample rate alone when bit depth is unknown', () => {
|
||||
const info = { suffix: 'FLAC', sampleRate: 192000 }
|
||||
render(<QualityInfo record={info} />)
|
||||
expect(screen.getByText('FLAC 192')).toBeInTheDocument()
|
||||
})
|
||||
it('renders stream details for other lossless containers', () => {
|
||||
const info = { suffix: 'WAV', sampleRate: 48000, bitDepth: 32 }
|
||||
render(<QualityInfo record={info} />)
|
||||
expect(screen.getByText('WAV 48/32')).toBeInTheDocument()
|
||||
})
|
||||
it('leaves DSD showing the container alone', () => {
|
||||
const info = { suffix: 'DSF', sampleRate: 2822400, bitDepth: 1 }
|
||||
render(<QualityInfo record={info} />)
|
||||
expect(screen.getByText('DSF')).toBeInTheDocument()
|
||||
})
|
||||
it('ignores stream details for lossy formats', () => {
|
||||
const info = { suffix: 'MP3', bitRate: 320, sampleRate: 44100 }
|
||||
render(<QualityInfo record={info} />)
|
||||
expect(screen.getByText('MP3 320')).toBeInTheDocument()
|
||||
})
|
||||
it('only render suffix and bitrate for lossy formats', () => {
|
||||
const info = {
|
||||
suffix: 'MP3',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue