3

私はiOS音楽アプリ(C ++で記述)に取り組んでおり、モデルは多かれ少なかれ次のようになっています。

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

つまり、基本的に、aSongには複数Tracks、aにTrackは複数、 PatternsaにはPattern複数がありますNotes.。これらはそれぞれクラスによって表され、Songオブジェクトを除いて、すべてベクトル内に格納されます。

それぞれNote"frame"パラメーターがあり、ノートをいつ演奏するかを計算できます。たとえば、44100サンプル/秒があり、特定のノートのフレームが132300である場合、3秒目の開始時にそのノートが必要であることがわかります。

私の質問は、最高のパフォーマンスを得るためにこれらのメモをどのように表現する必要があるかということです。今、私は各パターンのベクトルデータメンバーにノートを保存し、すべてをTracksループすることを考えていSongます。PatternsそしてループするNotesよりも、132300より大きく176400より小さいフレームデータメンバーを持っているものを確認します( 4秒の開始)。

お分かりのように、それは多くのループであり、曲は10分にもなる可能性があります。したがって、これがすべてのフレームを計算して時間どおりにバッファに送信するのに十分な速度であるかどうか疑問に思っています。

4

4 に答える 4

4

覚えておくべきことの1つは、パフォーマンスを向上させるには、通常、メモリ消費量を増やす必要があるということです。同じデータを異なる方法で2回保存したいと思うので、この場合も関連性があります(そして正当化されます) 。

まず、曲の基本構造は次のとおりです。

map<Track, vector<Pattern>> tracks;

TrackそれぞれをsのベクトルにマップしますPattern。トラックの順序は気にしないので、マップは問題ありません。

TracksとsのトラバースPatternは、それらの量が多くないため、高速である必要があります(私は推測します)。主なパフォーマンスの懸念は、何千ものノートをループすることです。これが私がそれを解決するために提案する方法です:

まず、オブジェクトごとに、メインのデータストレージとしてを使用Patternする必要があります。最初に、の内容のvector<Note>すべての変更をこれに書き込みます。Patternvector<Note>

vector<Note> notes;

また、パフォーマンスを考慮して、メモを保存する2番目の方法を使用できます。

map<int, vector<Notes>> measures;

これは、aの各メジャーを(その数で)このメジャーに含まれるsPatternのベクトルにマップします。Noteメインnotesストレージのデータが変更されるたびに、のデータにも同じ変更が適用されますmeasures。また、別のスレッドで、再生前に1回だけ、または再生中にも実行できます。

もちろん、2つのデータソースを同期することなく、メモをメジャーに保存することしかできませんでした。しかし、メモの束に大量の操作を適用する必要がある場合は、作業があまり便利ではない可能性があります。

再生中、次の小節が始まる前に、次のアルゴリズムが(大まかに)発生します。

  1. すべてのトラックで、すべてのパターンを見つけますpattern->startTime <= [current playback second] <= pattern->endTime
  2. パターンごとに、現在のメジャー番号を計算vector<Notes>し、マップから対応するメジャーを取得しmeasuresます。
  3. これで、次の小節(2番目?)が始まるまで、現在の小節の音符をループするだけで済みます。
于 2012-04-17T12:31:42.683 に答える
3

それらのベクトルをソートしたままにしてください。

再生中は、最後のノートプレーヤーの各ベクトルにポインター(インデックス)を保持するだけです。新しいメモを検索するには、各ベクトルで次のメモを確認する必要があります。メモをループする必要はありません。

于 2012-04-18T02:58:03.710 に答える
1

ベクトルを並べ替えて、試してみてください。これはより重要であり、ここで受け取ることができるすべての回答です。

すべての質問について、テストプロトタイプを使用して回答する必要があります。そうすれば、問題があるかどうかさえわかります。また、試してみると、理論だけでは通常は見られないことがわかります。

于 2012-04-18T23:38:34.903 に答える
0

そして私のモデルは多かれ少なかれこのように見えます:

いくつかの非常に重要な概念がモデルから欠落しています。

  1. テンポ。
  2. ダイナミクス
  3. ペダル
  4. 楽器
  5. 拍子記号
  6. (オプション)調性。
  7. エフェクト(残響/コーラス、ピッチホイール)。
  8. ステレオポジショニング。
  9. 歌詞。
  10. コードマップ。
  11. 作曲家情報/タイトル。

各ノートには「フレーム」パラメーターがあるので、ノートをいつ再生するかを計算できます。

いくつかの非常に重要な概念がモデルから欠落しています。

  1. アーティキュレーション。
  2. アフタータッチ。
  3. 期間に注意してください。

lilypondを見てみることをお勧めします。これは植字ソフトウェアですが、人間が読める形式で音楽を表現する最も正確な方法の1つでもあります。

私の質問は、最高のパフォーマンスを得るためにこれらのメモをどのように表現する必要があるかということです。

それらをすべて入れて、std::map<Timestamp, Note>lower_bound/upper_boundを使用して再生したいセグメントを見つけます。または、データが並べ替えられている限り、フラットstd::vectorでバイナリ検索することもできます。

「ブザー」を作成したい場合を除いて、音楽アプリケーションの作成は思ったよりもはるかに困難です。別のプロジェクトを試すことを強くお勧めします。

于 2012-04-12T04:14:33.357 に答える