未验证 提交 69d1dd0d 编写于 作者: P Peter Pan 提交者: GitHub

Minor bug fix in sample pages (#720)

* fix: get sample rate from wav raw

* feat: add sample indicator in sample pages

* fix: use query string to disable font cache
上级 e02db1d6
...@@ -210,7 +210,7 @@ const Audio = React.forwardRef<AudioRef, AudioProps & WithStyled>(({src, cache, ...@@ -210,7 +210,7 @@ const Audio = React.forwardRef<AudioRef, AudioProps & WithStyled>(({src, cache,
} }
}); });
const buffer = await data.data.arrayBuffer(); const buffer = await data.data.arrayBuffer();
await p.load(buffer); await p.load(buffer, data.type ?? undefined);
setDecoding(false); setDecoding(false);
setDuration(formatDuration(p.duration)); setDuration(formatDuration(p.duration));
onLoad?.({sampleRate: p.sampleRate, duration: p.duration}); onLoad?.({sampleRate: p.sampleRate, duration: p.duration});
......
import Audio, {AudioProps, AudioRef} from '~/components/Audio'; import Audio, {AudioProps, AudioRef} from '~/components/Audio';
import React, {FunctionComponent, useCallback, useState} from 'react'; import React, {FunctionComponent, useCallback, useState} from 'react';
import SampleChart, {SampleChartBaseProps} from '~/components/SamplePage/SampleChart'; import SampleChart, {SampleChartBaseProps} from '~/components/SamplePage/SampleChart';
import {rem, size, textLighterColor} from '~/utils/style';
import {format} from 'd3-format'; import {format} from 'd3-format';
import {size} from '~/utils/style';
import styled from 'styled-components'; import styled from 'styled-components';
import {useTranslation} from '~/utils/i18n'; import {useTranslation} from '~/utils/i18n';
...@@ -14,11 +14,6 @@ const StyledAudio = styled(Audio)` ...@@ -14,11 +14,6 @@ const StyledAudio = styled(Audio)`
flex-shrink: 1; flex-shrink: 1;
`; `;
const AudioInfo = styled.span`
color: ${textLighterColor};
font-size: ${rem(12)};
`;
const cache = 5 * 60 * 1000; const cache = 5 * 60 * 1000;
type AudioChartProps = SampleChartBaseProps; type AudioChartProps = SampleChartBaseProps;
...@@ -46,11 +41,11 @@ const AudioChart: FunctionComponent<AudioChartProps> = ({...props}) => { ...@@ -46,11 +41,11 @@ const AudioChart: FunctionComponent<AudioChartProps> = ({...props}) => {
type="audio" type="audio"
cache={cache} cache={cache}
footer={ footer={
<AudioInfo> <span>
{t('sample:sample-rate')} {t('sample:sample-rate')}
{t('common:colon')} {t('common:colon')}
{sampleRate} {sampleRate}
</AudioInfo> </span>
} }
content={content} content={content}
{...props} {...props}
......
import React, {FunctionComponent, useCallback, useEffect, useMemo, useRef, useState} from 'react'; import React, {FunctionComponent, useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {ellipsis, em, primaryColor, rem, size, textLightColor} from '~/utils/style'; import {ellipsis, em, primaryColor, rem, size, textLightColor, textLighterColor} from '~/utils/style';
import ChartToolbox from '~/components/ChartToolbox'; import ChartToolbox from '~/components/ChartToolbox';
import GridLoader from 'react-spinners/GridLoader'; import GridLoader from 'react-spinners/GridLoader';
...@@ -78,6 +78,16 @@ const Footer = styled.div` ...@@ -78,6 +78,16 @@ const Footer = styled.div`
justify-content: space-between; justify-content: space-between;
`; `;
const FooterInfo = styled.div`
color: ${textLighterColor};
font-size: ${rem(12)};
> * {
display: inline-block;
margin-left: ${rem(10)};
}
`;
type SampleData = { type SampleData = {
step: number; step: number;
wallTime: number; wallTime: number;
...@@ -221,7 +231,14 @@ const SampleChart: FunctionComponent<SampleChartProps> = ({run, tag, running, ty ...@@ -221,7 +231,14 @@ const SampleChart: FunctionComponent<SampleChartProps> = ({run, tag, running, ty
} }
]} ]}
/> />
{footer} <FooterInfo>
<span>
{t('sample:sample')}
{t('common:colon')}
{data?.length ? `${step + 1}/${data.length}` : '--/--'}
</span>
{footer}
</FooterInfo>
</Footer> </Footer>
</Wrapper> </Wrapper>
); );
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
"download-audio": "Download $t(audio)", "download-audio": "Download $t(audio)",
"download-image": "Download $t(image)", "download-image": "Download $t(image)",
"image": "image", "image": "image",
"sample": "Sample",
"sample-rate": "Sample Rate", "sample-rate": "Sample Rate",
"show-actual-size": "Show Actual Image Size", "show-actual-size": "Show Actual Image Size",
"step": "Step", "step": "Step",
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
"download-audio": "下载$t(audio)", "download-audio": "下载$t(audio)",
"download-image": "下载$t(image)", "download-image": "下载$t(image)",
"image": "图片", "image": "图片",
"sample": "样本",
"sample-rate": "采样率", "sample-rate": "采样率",
"show-actual-size": "按真实大小展示", "show-actual-size": "按真实大小展示",
"step": "Step", "step": "Step",
......
...@@ -9,6 +9,7 @@ export class AudioPlayer { ...@@ -9,6 +9,7 @@ export class AudioPlayer {
private gain: GainNode; private gain: GainNode;
private source: AudioBufferSourceNode | null = null; private source: AudioBufferSourceNode | null = null;
private buffer: AudioBuffer | null = null; private buffer: AudioBuffer | null = null;
private decodedSampleRate: number = Number.NaN;
private startAt = 0; private startAt = 0;
private stopAt = 0; private stopAt = 0;
...@@ -38,7 +39,7 @@ export class AudioPlayer { ...@@ -38,7 +39,7 @@ export class AudioPlayer {
if (!this.buffer) { if (!this.buffer) {
return Number.NaN; return Number.NaN;
} }
return this.buffer.sampleRate; return Number.isNaN(this.decodedSampleRate) ? this.buffer.sampleRate : this.decodedSampleRate;
} }
get volumn() { get volumn() {
...@@ -75,8 +76,25 @@ export class AudioPlayer { ...@@ -75,8 +76,25 @@ export class AudioPlayer {
} }
} }
load(buffer: ArrayBuffer) { static getWavSampleRate(buffer: ArrayBuffer) {
const intArr = new Int8Array(buffer);
const sampleRateArr = intArr.slice(24, 28);
return (
(sampleRateArr[0] & 0xff) |
((sampleRateArr[1] & 0xff) << 8) |
((sampleRateArr[2] & 0xff) << 16) |
((sampleRateArr[3] & 0xff) << 24)
);
}
load(buffer: ArrayBuffer, type?: string) {
this.reset(); this.reset();
if (type === 'audio/wave') {
this.decodedSampleRate = AudioPlayer.getWavSampleRate(buffer);
} else {
this.decodedSampleRate = Number.NaN;
}
return this.context.decodeAudioData(buffer, audioBuffer => { return this.context.decodeAudioData(buffer, audioBuffer => {
this.buffer = audioBuffer; this.buffer = audioBuffer;
}); });
......
...@@ -14,9 +14,13 @@ export {default as styled} from 'styled-components'; ...@@ -14,9 +14,13 @@ export {default as styled} from 'styled-components';
export * from 'styled-components'; export * from 'styled-components';
export * from 'polished'; export * from 'polished';
// rename conflict shorthands // rename conflict shorthands
export {borderRadius as borderRadiusShortHand, borderColor as borderColorShortHand} from 'polished'; export {
borderRadius as borderRadiusShortHand,
borderColor as borderColorShortHand,
fontFace as fontFaceShortHand
} from 'polished';
const {math, size, lighten, darken, normalize, fontFace, transitions, border, position} = polished; const {math, size, lighten, darken, normalize, transitions, border, position} = polished;
export const iconFontPath = `${PUBLIC_PATH}/style/fonts/vdl-icon`; export const iconFontPath = `${PUBLIC_PATH}/style/fonts/vdl-icon`;
...@@ -97,6 +101,36 @@ export const transitionProps = (props: string | string[], args?: string | {durat ...@@ -97,6 +101,36 @@ export const transitionProps = (props: string | string[], args?: string | {durat
} }
return transitions(props, args); return transitions(props, args);
}; };
export const fontFace = ({queryString, ...args}: {queryString?: string} & Parameters<typeof polished.fontFace>[0]) => {
const formatMap: Record<string, string> = {
eot: 'embedded-opentype',
woff2: 'woff2',
woff: 'woff',
ttf: 'truetype',
svg: 'svg'
};
const f = polished.fontFace(args);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const src: string = (f['@font-face'] as any).src;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(f['@font-face'] as any).src = src.replace(/url\(['"](.*?)\.(\w*?)['"]\)/g, (_, path: string, format: string) => {
let replace = `url("${path}.${format}`;
if (queryString) {
replace += `?${queryString}`;
}
if (format === 'svg') {
replace += `#${args.fontFamily}`;
}
replace += '")';
if (formatMap[format]) {
replace += ` format("${formatMap[format]}")`;
}
return replace;
});
return f;
};
export const link = css` export const link = css`
a { a {
color: ${primaryColor}; color: ${primaryColor};
...@@ -131,6 +165,7 @@ export const GlobalStyle = createGlobalStyle` ...@@ -131,6 +165,7 @@ export const GlobalStyle = createGlobalStyle`
${normalize} ${normalize}
${fontFace({ ${fontFace({
queryString: 'wxo6ka',
fontFamily: 'vdl-icon', fontFamily: 'vdl-icon',
fontFilePath: iconFontPath, fontFilePath: iconFontPath,
fileFormats: ['ttf', 'woff', 'svg'], fileFormats: ['ttf', 'woff', 'svg'],
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册