gpt4 book ai didi

c++ - 为特定时间快速搜索音符建模音乐(音符)的最佳方式

转载 作者:太空狗 更新时间:2023-10-29 20:06:01 29 4
gpt4 key购买 nike

我正在开发一个 iOS 音乐应用程序(用 C++ 编写),我的模型看起来或多或少像这样:

--Song
----Track
----Track
------Pattern
------Pattern
--------Note
--------Note
--------Note

所以基本上一首 Song 有多个 Track,一个 Track 可以有多个 Pattern 和一个 Pattern 有多个 Notes。 这些东西中的每一个都由一个类表示,除了 Song 对象外,它们都存储在 vector 中。

每个 Note 都有一个 "frame" 参数,这样我就可以计算出应该播放音符的时间。例如,如果我有 44100 个样本/秒并且特定音符的帧是 132300,我知道我需要在第三秒开始时的音符。

我的问题是我应该如何表示这些音符以获得最佳性能?现在我正在考虑将音符存储在每个模式的 vector 数据成员中,然后循环播放 Song 的所有 Tracks,然后查看 Patterns 然后循环 Notes 以查看哪个帧数据成员大于 132300 且小于 176400(第 4 秒开始)。

如您所知,循环次数很多,一首歌可能长达 10 分钟。所以我想知道这是否足够快以计算所有帧并将它们按时发送到缓冲区。

最佳答案

您应该记住的一件事是,要提高性能,通常必须增加内存消耗。在这种情况下它也是相关的(并且是合理的),因为我相信您希望以不同的方式将相同的数据存储两次

首先,您应该了解一首歌曲的基本结构:

map<Track, vector<Pattern>> tracks;

它映射每个 TrackPattern 的 vector 秒。 map 很好,因为您不关心轨道的顺序。

遍历Track s 和 Pattern s 应该很快,因为它们的数量不会很高(我假设)。主要的性能问题是循环遍历数千个音符。以下是我建议的解决方法:

首先,对于每个Pattern对象你应该有一个 vector<Note>作为您的主要数据存储。您将在 Pattern 上写入所有更改vector<Note> 的内容首先。

vector<Note> notes;

并且出于性能考虑,您可以有第二种存储笔记的方式:

map<int, vector<Notes>> measures;

这将在 Pattern 中映射每个 measure(按其编号)到 Note 的 vector 包含在该措施中。每次主数据发生变化时notes存储,您将对 measures 中的数据应用相同的更改.您也可以在播放之前每次只执行一次,或者甚至在单独的线程中同时播放。

当然,您可以只将注释存储在度量中,而不必同步两个数据源。但是,当您必须对一堆笔记应用大量操作时,使用它可能不太方便。

在播放过程中,在下一个小节开始之前,会发生以下算法(大致):

  1. 在每个轨道中,找到所有模式,其中 pattern->startTime <= [current playback second] <= pattern->endTime .
  2. 对于每个模式,计算当前小节数并得到vector<Notes>对于来自 measures 的相应度量 map 。
  3. 现在,在下一个小节(第二个?)开始之前,您只需循环当前小节的音符。

关于c++ - 为特定时间快速搜索音符建模音乐(音符)的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10080165/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com