musicLine(iOS)についての進捗。
フレーズツールの実装が大体完了したので報告します。
ただし現在は描画に不具合があり、フレーズツールの操作がわかりづらくなっています。
例えば、フレーズダイアログで作成ボタンをタップしても反応がありません。正確に言えば実際はフレーズを作成したんだけど、画面の描画が行われずに作成できてないような表示になります。
これはモデルの通知機構に問題があり、モデルの変更を適切に監視できてないことが要因になります。今後通知機構について見直していきます。
現在は、暫定処置として画面をスクロールすることで画面を強制的に描画しています。
実装状況
カテゴリ | タイトル | 補足 | |
View | |||
Composition UI配置
ガイド表示 | ツールガイド(フレーズ) | フレーズ移動・伸縮のバー、選択範囲テキスト(iOS独自) | |
フレーズボタン | フレーズボタンとサブボタンを配置、ツールに応じてアイコンを変更、画面拡大率に応じて縮小 | ||
フレーズタブ | ツールに応じてアイコンを変更、拡大率に応じて縮小、スクロール状態に応じて移動 | ||
Dialog ダイアログ
| フレーズ | フレーズの作成・設定・挿入、フレーズの長さやリピート回数の設定 | |
Composition | |||
Common 作曲共通
| 通知機構 | Modelに変更があった時に、Viewへ通知して再描画。変更状況を監視してキャッシュ | |
PhraseTool フレーズツール
フレーズの編集 | データ構造 | トラックのフレーズを取得・追加、削除、状態 | |
フレーズの作成・挿入 | ダイアログで長さとリピートを設定 | ||
フレーズの選択 | 2点タップで範囲選択、範囲ガイドタップで選択解除(仕様変更) | ||
フレーズの移動 | 左右スワイプで移動、移動は選択フレーズとスワイプ中のフレーズを含む | ||
フレーズの伸縮 | サブ編集領域をスワイプした時にフレーズ長さを伸縮、長さ0で削除(iOS独自) | ||
フレーズの貼り付け | 選択フレーズをコピー・ペースト、サブボタンかフレーズタブタップで挿入、選択解除 | ||
周囲有無判定 | 作成する小節の近くにフレーズがあるかの判定、設定できる長さやリピート回数の制御 | ||
フレーズボタン・タブ | ツールに応じてフレーズボタン、タブの処理を変更 |
全進捗マップを表示
カテゴリ | タイトル | 補足 | |
View | |||
Composition UI配置
ガイド表示 | ピアノ | ||
スクロールエリア | |||
小節番号 | |||
小節線 | |||
分割線 | 拡大率によって間隔を変化 | ||
フレーズ | フレーズがないところはフレーズ作成ボタンを表示 | ||
ツールボタン | 選択中のツールはツール色にハイライトする | ||
メロディーライン | ペンツールでの音符作成時の入力線 | ||
メロディー音符 | 音符の先頭にチョボをつける | ||
リズム音符 | ベース音符のみ下に表示 | ||
サンプルデータ | 手入力したサンプルデータの音符を配置 | ||
連符 | 連符は数字で表示、拡大率によって省略 | ||
ツールガイド(ペン) | 長さ編集しているリズム音符、伸ばした時の削る範囲 | ||
ツールガイド(指) | 移動中の音符影、矩形選択の枠 | ||
ツールガイド(消しゴム) | 削除範囲、和音のみの削除範囲 | ||
ツールガイド(フレーズ) | フレーズ移動・伸縮のバー、選択範囲テキスト(iOS独自) | ||
フレーズボタン | フレーズボタンとサブボタンを配置、ツールに応じてアイコンを変更、画面拡大率に応じて縮小 | ||
フレーズタブ | ツールに応じてアイコンを変更、拡大率に応じて縮小、スクロール状態に応じて移動 | ||
音符音階 | メロディ音符に音階表示 | ||
Community UI配置
| |||
Dialog ダイアログ
| フレーズ | フレーズの作成・設定・挿入、フレーズの長さやリピート回数の設定 | |
Composition | |||
Common 作曲共通
| データ構造 | 座標とサイズ、状態を保持する。レンダラーやコライダー、通知等のロジック | |
コンバーター | Domainのデータ構造へ変換・逆変換 | ||
通知機構 | Modelに変更があった時に、Viewへ通知して再描画。変更状況を監視してキャッシュ | ||
FingerTool 指ツール
音符の編集 | データ構造 | フレーズの音符を取得、基点と移動ベクトルを保持して移動する | |
音符の移動 | 和音や連符は上下のみに制御 | ||
音符の影 | 移動中に操作できているかわかりやすいように(iOS独自) | ||
内外判定 | 音符の移動をフレーズ内に留める | ||
衝突判定 | 移動する音符が他の音符に重なったときの挙動 | ||
タップ選択 | タップした音符の子音符も選択・解除 | ||
矩形選択 | 囲った音符を選択 | ||
音符の入れ替え | リズム音符のスライドで重なった音符と入れ替える(iOS独自) | ||
和音の削除 | 和音を移動した時に重なる時に削除する | ||
連符に切り替え | リズム音符タップで切り替え | ||
PenTool ペンツール
音符の作成 | データ構造 | 音符を作成・分割・統合、フレーズへ音符を追加する | |
音符の作成 | タップで音符を作成。分割線に合わせて長さを決定 | ||
音符列の作成 | スワイプに沿って複数の音符を作成。音階変わる時に音符分割 | ||
有無判定 | タップやスワイプした縦ラインに既に音符があるか判定 | ||
音符の移動 | 音符が既にある場合は、作成ではなく移動。一定距離進むと移動終了 | ||
音符の分割 | リズム音符をタップした時、音符を分割、メロディ線に沿ってY位置を動かす | ||
音符の統合 | 2つのリズム音符の間をタップした場合、音符を統合 | ||
音符の伸縮 | リズム音符を左右にスワイプすることで音符の長さを伸縮、始点で分割なし(仕様変更) | ||
音符の消滅 | 音符の伸縮をした時に長さが0になると削除する(iOS独自) | ||
領域差演算 | 音符伸縮で他の音符に重なる時は差演算して他の音符長さを削る | ||
サンプリング補間 | 素早くスワイプしても音符が移動できるようにサンプリング間を補間する | ||
細かい音符 | 分割線内の細かな音符を移動する挙動 | ||
EraserTool 消しゴムツール
音符の削除 | データ構造 | 和音と連符の認識、フレーズから音符を削除する | |
音符の削除 | タップで音符を削除 | ||
和音・連符の削除 | 和音・連符をタップで和音・連符のみを削除(iOS独自) | ||
音符種別判定 | タップした音符が和音・連符・ルート音符なのか判定する | ||
音符列の削除 | スワイプで指定する削除範囲内の複数の音符を削除。 | ||
和音列の削除 | リズム音符をスワイプで複数の和音のみを削除。(iOS独自) | ||
休符に切り替え | リズム音符タップで休符に切り替える | ||
PhraseTool フレーズツール
フレーズの編集 | データ構造 | トラックのフレーズを取得・追加、削除、状態 | |
フレーズの作成・挿入 | ダイアログで長さとリピートを設定 | ||
フレーズの選択 | 2点タップで範囲選択、範囲ガイドタップで選択解除(仕様変更) | ||
フレーズの移動 | 左右スワイプで移動、移動は選択フレーズとスワイプ中のフレーズを含む | ||
フレーズの伸縮 | サブ編集領域をスワイプした時にフレーズ長さを伸縮、長さ0で削除(iOS独自) | ||
フレーズの貼り付け | 選択フレーズをコピー・ペースト、サブボタンかフレーズタブタップで挿入、選択解除 | ||
周囲有無判定 | 作成する小節の近くにフレーズがあるかの判定、設定できる長さやリピート回数の制御 | ||
フレーズボタン・タブ | ツールに応じてフレーズボタン、タブの処理を変更 | ||
StampTool スタンプツール
モチーフの編集 | |||
Transform 画面移動
座標変換 | 画面を上下移動 | ピアノのスワイプにより | |
画面を左右移動 | スクロールエリアのスワイプにより | ||
画面を拡大・縮小 | ピンチアウト・インにより基点を画面中心に設定する | ||
画面を拡大・縮小(軸指定) | 長押しからのドラッグ。ピアノでX軸方向、スクロールエリアでY軸方向 | ||
MIDI | |||
Common MIDI共通
| データ構造 | MIDIフォーマットへ出力できる構造 | |
コンバーター | Compositionのデータ構造へ変換・逆変換 | ||
Commnity | |||
Common コミュニティ
共通 | データ構造 | カテゴリ等の曲情報、いいねやお気に入り等のリスポンスを保持 | |
Domain | |||
データ構造 Json形式 | Melody | MelodyTrack, *MelodyPhrase, NoteContainer, NoteBlock, Note | |
Drum | DrumTrack, *DrumPhrase, BeatContainer, Beat | ||
共通化 | Original, Repeat, Syncの3種のPhraseをジェネリッククラスとプロトコルで抽象化 | ||
Service サービスモデル
| SongReder | Jsonファイルを読み込み、Domainのデータへ変換 | |
SongWriter | DomainのデータからJsonファイルへ書き出し | ||
Common | |||
Service サービスモデル
| MidiPlayer | Midiファイルを再生する | |
リポジトリ | 保存データを管理 |
フレーズツールの実装
フレーズの作成・挿入
フレーズボタンをタップした時に、フレーズを作成します。
フレーズの作成時にはダイアログを表示し、フレーズの長さやリピート回数を設定します。
また、フレーズサブボタンかフレーズタブをタップすることで、フレーズを挿入します。
フレーズの選択
フレーズをタップして選択します。
フレーズ外をタップすると選択解除になります。
なお、複数フレーズの飛び飛びでの選択はできず、2点タップすると2点間の範囲選択になります。
ちなみに、右上には選択しているフレーズの小節範囲が表示されます。その選択範囲のテキストをタップすることでも選択解除になります。
フレーズの移動
編集エリアを左右にスワイプして、フレーズを移動します。
フレーズを選択すると、複数のフレーズを一気に移動できます。
なお、選択フレーズとスワイプするフレーズの間にフレーズがある場合、挟まれたフレーズも一緒に移動します。
移動中は移動範囲がわかりやすいように、移動後の小節位置とバーを表示します。
フレーズの伸縮
サブ編集領域をスワイプすることで、フレーズの長さを伸縮します。
なおフレーズを短くした時、フレーズ外の音符は削除され、フレーズを跨いでいる音符は切断されます。
長さを0にすると、フレーズを削除します。
フレーズの貼り付け
フレーズボタンをタップすることで、選択フレーズをコピーして貼り付けます。
フレーズサブボタンかフレーズタブをタップすることで、選択フレーズをコピーして挿入します。
貼り付けた時、既にフレーズがある場合は上書きします。
周囲有無判定
フレーズを作成する時、近くにフレーズがあるかを判定します。近くにフレーズがある場合、設定できる長さやリピート回数を制限します。
選択フレーズをコピペする際にも、周囲フレーズの有無を判定して、フレーズの上書きや選択解除の制御をします。
フレーズボタン・タブ
ツールに応じてフレーズボタン等のアイコンや処理を変更します。
ツール | ボタン | サブボタン | タブ |
---|---|---|---|
ペン | フレーズ作成 | - | フレーズ設定 |
指 | - | - | フレーズ内音符 全選択/解除 |
消しゴム | 小節削除 | - | フレーズ削除 |
フレーズ 選択時 |
フレーズ作成 コピーペースト |
フレーズ挿入 コピー挿入 |
フレーズ挿入 コピー挿入 |
おわりに
フレーズツールはとりあえず実装できました。
描画不具合があると、本当にできているかわかりづらいですが。。
なので次に行く前に、まずはモデル通知機構の見直しをします。
無理やりしようとすれば、ジェスチャ入力時に全てのViewを再描画することでも不具合解消になります。でも、描画コスト的に良くないですね。
描画は最小限に抑えないと音符が多くなったときに動作が重くなりそうなので、この辺りはちゃんと最適化しておきたいところです。
またモデル変更を適切に監視できていると、コストが高いMIDIファイル書き出し処理も最小限に抑えられる等の利点もあります。