我正在制作一个带有节拍器的应用程序。我正在使用 react-native-sound 和 Animated。我需要节拍器的声音以非常高的精度触发,并且与动画同步。我没有大量经验,所以我使用了一个 hacky 解决方案(使用 Animated.listener 触发样本),但效率极低:
<Button
icon={this.state.paused ? <Icon name="play" size={25} color='white'/> : <Icon name="pause" size={25} color='white'/>}
onPress={() => {
if (this.state.paused)
{this.setState({paused: false});
this.animateTiming();
let loopCount = 0;
this.animatedValue.addListener(({value}) => {
loopCount++;
if(value==1) loopCount=0;
// metronome playback
if ([0,60,120,180].includes(loopCount)) playSound(audioList[0], 0);
});
}
有人对如何更好地处理它有任何建议吗?谢谢!
更新#2
this.animateTiming() 看起来像这样:
animateTiming(){
this.animatedValue.setValue(START_POINT);
Animated.loop(
Animated.timing(this.animatedValue, {
toValue: STOP_POINT,
easing: Easing.linear,
duration: 4000, //these are milliseconds
useNativeDriver: true
})
).start();
}
循环长度为 4000 毫秒,因此在 60fps 时 loopCount 上升到 240。因此,[0,60,120,180] 表示“每秒播放声音”。延迟发生在每个循环的开始,即调用渲染函数时。我已经确定延迟的来源(大约 80 毫秒)是使用 VexFlow 渲染乐谱(请参阅此链接中“入门”中的示例)。
问题是,VexFlow 渲染和动画是否有可能以某种方式并行运行(音频需要完全及时,渲染符号的轻微延迟不是问题)。预渲染符号是不可行的,因为显示的内容取决于用户在前一个循环周期中的操作。