Skip to content

Commit fa519c9

Browse files
committed
feat: some changes to the audio visualizer example
1 parent 5aa5fcc commit fa519c9

File tree

4 files changed

+85
-32
lines changed

4 files changed

+85
-32
lines changed

apps/common-app/src/components/Container.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,18 @@ import { colors } from '../styles';
88
type ContainerProps = PropsWithChildren<{
99
style?: StyleProp<ViewStyle>;
1010
centered?: boolean;
11+
disablePadding?: boolean;
1112
}>;
1213

1314
const headerPadding = 120; // eyeballed
1415

1516
const Container: React.FC<ContainerProps> = (props) => {
16-
const { children, style, centered } = props;
17+
const { children, style, centered, disablePadding } = props;
1718

1819
return (
1920
<SafeAreaView
2021
edges={['bottom', 'left', 'right']}
21-
style={[styles.basic, centered && styles.centered, style]}>
22+
style={[styles.basic, centered && styles.centered, !disablePadding && styles.padding, style]}>
2223
<BGGradient />
2324
{children}
2425
</SafeAreaView>
@@ -30,10 +31,12 @@ export default Container;
3031
const styles = StyleSheet.create({
3132
basic: {
3233
flex: 1,
33-
padding: 24,
3434
paddingTop: headerPadding,
3535
backgroundColor: colors.background,
3636
},
37+
padding: {
38+
padding: 24,
39+
},
3740
centered: {
3841
alignItems: 'center',
3942
justifyContent: 'center',

apps/common-app/src/examples/AudioVisualizer/AudioVisualizer.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import FreqTimeChart from './FreqTimeChart';
1212
import { Container, Button } from '../../components';
1313
import { layout } from '../../styles';
1414

15-
const FFT_SIZE = 256;
15+
const FFT_SIZE = 512;
1616

1717
const URL =
1818
'https://software-mansion-labs.github.io/react-native-audio-api/audio/music/example-music-02.mp3';
@@ -21,8 +21,11 @@ const AudioVisualizer: React.FC = () => {
2121
const [isPlaying, setIsPlaying] = useState(false);
2222
const [isLoading, setIsLoading] = useState(false);
2323

24-
const [times, setTimes] = useState<number[]>([]);
25-
const [freqs, setFreqs] = useState<number[]>([]);
24+
const [times, setTimes] = useState<number[]>(
25+
new Array(FFT_SIZE / 2).fill(127)
26+
);
27+
28+
const [freqs, setFreqs] = useState<number[]>(new Array(FFT_SIZE / 2).fill(0));
2629

2730
const audioContextRef = useRef<AudioContext | null>(null);
2831
const analyserRef = useRef<AnalyserNode | null>(null);
@@ -75,6 +78,7 @@ const AudioVisualizer: React.FC = () => {
7578
if (!analyserRef.current) {
7679
analyserRef.current = audioContextRef.current.createAnalyser();
7780
analyserRef.current.fftSize = FFT_SIZE;
81+
analyserRef.current.smoothingTimeConstant = 0.8;
7882

7983
analyserRef.current.connect(audioContextRef.current.destination);
8084
}
@@ -102,7 +106,7 @@ const AudioVisualizer: React.FC = () => {
102106
}, []);
103107

104108
return (
105-
<Container>
109+
<Container disablePadding>
106110
<View style={{ flex: 0.2 }} />
107111
<FreqTimeChart
108112
timeData={times}
@@ -127,6 +131,11 @@ const AudioVisualizer: React.FC = () => {
127131
};
128132

129133
const styles = StyleSheet.create({
134+
container: {
135+
flex: 1,
136+
justifyContent: 'center',
137+
alignItems: 'center',
138+
},
130139
button: {
131140
justifyContent: 'center',
132141
flexDirection: 'row',

apps/common-app/src/examples/AudioVisualizer/Charts.tsx

Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,35 @@ import {
99
} from '@shopify/react-native-skia';
1010

1111
import { useCanvas } from './Canvas';
12-
import { colors } from '../../styles';
1312
import { getPointCX, getPointCY } from '../DrumMachine/utils';
1413

1514
const INNER_RADIUS = 90;
1615
const OUTER_RADIUS = 150;
1716

17+
interface Point {
18+
x1: number;
19+
y1: number;
20+
x2: number;
21+
y2: number;
22+
color: string;
23+
}
24+
1825
export function getAngle(stepIdx: number, maxSteps: number) {
1926
return (stepIdx / maxSteps) * Math.PI * 2 - Math.PI / 2;
2027
}
2128

29+
function sampleExp(value: number) {
30+
return Math.exp(2.5 * value) / 4 - 0.2;
31+
}
32+
33+
function weightWithIndex(value: number, index: number, indexMax: number) {
34+
if (index < indexMax / 2) {
35+
return value * Math.max(index / (indexMax / 2), 0.5);
36+
}
37+
38+
return value;
39+
}
40+
2241
interface ChartLineProps {
2342
data: number[];
2443
frequencyBinCount: number;
@@ -31,9 +50,9 @@ const TimeChartLine: React.FC<ChartLineProps> = (props) => {
3150
const circlePaint = useMemo(() => {
3251
const paint = Skia.Paint();
3352
paint.setAntiAlias(true);
34-
paint.setColor(Skia.Color(colors.main));
53+
paint.setColor(Skia.Color('#FFD61E'));
3554
paint.setStyle(PaintStyle.Stroke);
36-
paint.setStrokeWidth(3);
55+
paint.setStrokeWidth(6);
3756
return paint;
3857
}, []);
3958

@@ -57,15 +76,10 @@ const TimeChartLine: React.FC<ChartLineProps> = (props) => {
5776
<Circle
5877
cx={size.width / 2}
5978
cy={size.height / 2}
60-
r={INNER_RADIUS * 1.33}
79+
r={140}
6180
paint={circlePaint}
6281
/>
63-
<Points
64-
points={points}
65-
mode="polygon"
66-
color={colors.main}
67-
strokeWidth={2}
68-
/>
82+
<Points points={points} mode="polygon" color="#B5E1F1" strokeWidth={2} />
6983
</>
7084
);
7185
};
@@ -74,43 +88,71 @@ const FrequencyChartLine: React.FC<ChartLineProps> = (props) => {
7488
const { size } = useCanvas();
7589
const { data, frequencyBinCount } = props;
7690

77-
const points = useMemo(() => {
91+
const { points, barWidth } = useMemo(() => {
7892
const maxHeight = size.height;
7993
const maxWidth = size.width;
80-
const barWidth = maxWidth / frequencyBinCount;
94+
const bw = (Math.PI * 150) / (frequencyBinCount - 64);
8195

82-
return data.map((value, index) => {
83-
const angle = getAngle(index, frequencyBinCount);
84-
const x = getPointCX(angle, OUTER_RADIUS, maxWidth / 2);
85-
const y = getPointCY(angle, OUTER_RADIUS, maxHeight / 2);
96+
const p: Point[] = [];
97+
98+
function getPoint(
99+
index: number,
100+
value: number,
101+
color: string,
102+
ogIndex: number
103+
) {
104+
const angle = getAngle(index - 32, 2 * (frequencyBinCount - 64));
105+
const x1 = getPointCX(angle, OUTER_RADIUS, maxWidth / 2);
106+
const y1 = getPointCY(angle, OUTER_RADIUS, maxHeight / 2);
86107

87108
const x2 = getPointCX(
88109
angle,
89-
OUTER_RADIUS + (Math.max(value, 10) / 256.0) * 30,
110+
OUTER_RADIUS +
111+
sampleExp(
112+
weightWithIndex(value / 255.0, ogIndex, frequencyBinCount)
113+
) *
114+
40,
90115
maxWidth / 2
91116
);
117+
92118
const y2 = getPointCY(
93119
angle,
94-
OUTER_RADIUS + (Math.max(value, 10) / 256.0) * 30,
120+
OUTER_RADIUS +
121+
sampleExp(
122+
weightWithIndex(value / 255.0, ogIndex, frequencyBinCount)
123+
) *
124+
40,
95125
maxHeight / 2
96126
);
97127

98-
const hue = 180 + (index / frequencyBinCount) * 60;
99-
const color = `hsla(${hue}, 100%, 50%, 40%)`;
100-
return { color, x, y, x2, y2, barWidth };
128+
return { color, x1, y1, x2, y2 };
129+
}
130+
131+
data.forEach((value, index) => {
132+
if (index < 32 || index >= frequencyBinCount - 32) {
133+
return;
134+
}
135+
136+
const hue = 180 + 20 * (index / frequencyBinCount);
137+
const color = `hsla(${hue}, 100%, 50%, 80%)`; // '#E1F3FA';
138+
139+
p.push(getPoint(index, value, color, index));
140+
p.push(getPoint(2 * frequencyBinCount - 65 - index, value, color, index));
101141
});
142+
143+
return { points: p, barWidth: bw };
102144
}, [size, data, frequencyBinCount]);
103145

104146
return (
105147
<>
106148
{points.map((point, index) => (
107149
<Line
108150
key={index}
109-
p1={vec(point.x, point.y)}
151+
p1={vec(point.x1, point.y1)}
110152
p2={vec(point.x2, point.y2)}
111153
style="stroke"
112-
strokeWidth={point.barWidth}
113154
color={point.color}
155+
strokeWidth={barWidth}
114156
/>
115157
))}
116158
</>

apps/common-app/src/examples/DrumMachine/Grid.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ const Grid: React.FC = () => {
4949
cx={cPoint.x}
5050
cy={cPoint.y}
5151
color="transparent"
52-
r={instrument.radius}
53-
>
52+
r={instrument.radius}>
5453
<Paint
5554
style="stroke"
5655
color={colors.border}

0 commit comments

Comments
 (0)